RequiresNewPropagation
: 开启独立的新事务
/**
* Created by caojialin
* Date: 2019-08-15 20:09
* Description: 独立于原事务外, 重新开启一个新事务, 此事务与原事务独立互不影响
*/
@Component
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Array(classOf[Throwable]))
class RequiresNewPropagation {
val LOGGER: Logger = LoggerFactory.getLogger(getClass)
def invoke[A, B](req: => A)(func: => A => B): B = {
LOGGER.debug("start a new transaction ...")
val resp = func(req)
LOGGER.debug("finish a new transaction .")
resp
}
}
PropagationUtil
: 工具Bean
object PropagationUtil {
private val LOGGER: Logger = LoggerFactory.getLogger(getClass)
@Resource
var requiresNewPropagation: RequiresNewPropagation = _
/**
* 重新开启一个事务
* @param req
* @param func
* @tparam A
* @tparam B
* @return Assert.assert 抛出的异常 被代理 最终异常为 UndeclaredThrowableException 类型
* 异常信息: e.getUndeclaredThrowable.getMessage
*/
def requiresNew[A, B](req: => A)(func: => A => B): B = {
requiresNewPropagation.invoke(req)(func)
}
/**
* 异常捕获 不影响后续事务
* @param req
* @param func
* @tparam A
* @tparam B
*/
def requiresNewWithTry[A, B](req: => A)(func: => A => B): Unit = {
try {
requiresNewPropagation.invoke(req)(func)
} catch {
case e: Throwable => LOGGER.error(s"catch exception in a requires new transaction: ", e)
}
}
}
注意: 由于scala的object不支持注解, 所以需要在配置文件配置bean, 以便于注入RequiresNewPropagation
<bean id="propagationUtil" class="com.wanbo.service.order.common.PropagationUtil$" />
PropagationUtilTest
: 测试类
/**
* Created by caojialin
* Date: 2019-08-16 10:11
* Description:
*/
@RunWith(classOf[SpringJUnit4ClassRunner])
@ContextConfiguration(locations = Array("classpath:META-INF/spring/services.xml"))
@Transactional
@Rollback(false) //事物不回滚
class PropagationUtilTest {
// 1-4成功插入数据库, 5失败回滚, 后续不再执行
@Test
def requiresNewTest(): Unit = {
1.to(9).foreach {
PropagationUtil.requiresNew(_)( id =>
mysqlData.executeUpdate(sql"insert into test set id = $id")
if (id % 5 == 0) {
Assert.assert(assertion = false, OrderException.bizFault("异常数据"))
}
)
}
}
// 10,15插入失败, 但异常被捕获, 不影响其他事务, 11-14,16-19成功插入
@Test
def requiresNewWithTryTest(): Unit = {
10.to(19).foreach {
PropagationUtil.requiresNewWithTry(_)( id =>
mysqlData.executeUpdate(sql"insert into test set id = $id")
if (id % 5 == 0) {
Assert.assert(assertion = false, OrderException.bizFault("异常数据"))
}
)
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。