嵌套事务场景中的@Transactional - 在RW和RO连接之间切换

时间:2017-12-22 05:29:17

标签: spring spring-boot spring-transactions

我有一个场景,我想在readOnly事务中执行child1,在读写事务中执行child2,并且都在一个过度的事务中执行。 如果child1或child2出现问题,我只想回滚过度的事务。

 var options = new MobileBarcodeScanningOptions
 {
     AutoRotate = true,
     UseNativeScanning = true,
     TryHarder = true,
     TryInverted = true,
     UseFrontCameraIfAvailable  = true
 };

 var scannedCode = await _scanner.Scan(options);

输出日志显示:

@Transactional
parentMethod(){
  TransactionSynchronizationManager
  .setCurrentTransactionName("TestTransaction");
  log.info("Current Transaction Name - parentMethod ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - parentMethod ::: " + 
  TransactionSynchronizationManager.isCurrentTransactionReadOnly());
  child1();
  child2();
}

@Transactional(readOnly=true)
child1(){
  log.info("Current Transaction Name - child1 ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - child1 ::: " + 
  TransactionSynchronizationManager
  .isCurrentTransactionReadOnly());
}

@Transactional
child2(){
  log.info("Current Transaction Name - child2 ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - child2 ::: " + 
  TransactionSynchronizationManager
  .isCurrentTransactionReadOnly());
}

然而,如果我故意在child1方法中设置 TransactionSynchronizationManager.setCurrentTransactionReadOnly(true),则输出会像我预期的那样轻微变化。

Current Transaction Name - parentMethod ::: TestTransaction
Is the transaction readonly - parentMethod ::: false
Current Transaction Name - child1 ::: null
Is the transaction readonly - child1 ::: false
Current Transaction Name - child2 ::: null
Is the transaction readonly - child2 ::: false

输出日志显示:

@Transactional(readOnly=true)
child1(){
  TransactionSynchronizationManager
  .setCurrentTransactionReadOnly(true);
  log.info("Current Transaction Name - child1 ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - child1 ::: " + 
  TransactionSynchronizationManager
  .isCurrentTransactionReadOnly());
}

我只是想知道我做的事情是否有问题。或者有更好的方法来做到这一点。但是,child1和child2中的当前事务名称仍为null,我希望它是“TestTransaction”,它是在parentMethod中设置的。

另外,只是想知道哪一个优先,readOnly或传播级别存在嵌套事务时这些值设置不同。

1 个答案:

答案 0 :(得分:0)

@Transactional
parentMethod(){
  TransactionSynchronizationManager
  .setCurrentTransactionName("TestTransaction");
  log.info("Current Transaction Name - parentMethod ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - parentMethod ::: " + 
  TransactionSynchronizationManager.isCurrentTransactionReadOnly());
  child1();
  child2();
}

child1(){
  TransactionSynchronizationManager
  .setCurrentTransactionReadOnly(true);
  log.info("Current Transaction Name - child1 ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - child1 ::: " + 
  TransactionSynchronizationManager
  .isCurrentTransactionReadOnly());
    TransactionSynchronizationManager
  .setCurrentTransactionReadOnly(false);
}

child2(){
  log.info("Current Transaction Name - child2 ::: " + 
  TransactionSynchronizationManager
  .getCurrentTransactionName());
  log.info("Is the transaction readonly - child2 ::: " + 
  TransactionSynchronizationManager
  .isCurrentTransactionReadOnly());
}

这似乎对我有用。我在这里混合处理事务的程序化和声明性方式。我在@Transactional上只有一个过度拱形的parentMethod注释,并在需要时明确设置和取消设置readonly。有人可以就此发表评论或意见吗?