Java Spring@Transactional隔离传播
是否可以在同一事务之间更改隔离级别 我有一个用例,我希望使用SpringDataJpa的saveAndFlush持久化的未限制数据在不同的事务中可用,或者使内部事务提交数据,但在外部事务中出现任何异常时应该能够回滚 这是必要的,因为我想更新资源,并且在锁表中有一个条目,以避免并发更新。数据库中的锁表在更新事务完成之前不会得到更新,因此我希望将数据提交到锁表,同时在更新操作期间出现任何异常时应回滚。Java Spring@Transactional隔离传播,java,spring,spring-boot,spring-data-jpa,transactional,Java,Spring,Spring Boot,Spring Data Jpa,Transactional,是否可以在同一事务之间更改隔离级别 我有一个用例,我希望使用SpringDataJpa的saveAndFlush持久化的未限制数据在不同的事务中可用,或者使内部事务提交数据,但在外部事务中出现任何异常时应该能够回滚 这是必要的,因为我想更新资源,并且在锁表中有一个条目,以避免并发更新。数据库中的锁表在更新事务完成之前不会得到更新,因此我希望将数据提交到锁表,同时在更新操作期间出现任何异常时应回滚。 具有@Transactional的Service1方法将调用Service2的方法。Service
@Service
class Service1{
@Autowired
Service2 service2;
@Transactional
public void method1(){
Foo foo=new Foo();
foo.setId("f123");
service2.saveValue(foo);
}
}
@Service
@Transactional(isolation=Isolation.READ_UNCOMMITTED)
class Service2{
@Autowired
FooRepository fooRepository;
public void saveValue(Foo value){
fooRepository.saveAndFlush(value);
}
}
public interface FooRepository extends JpaRepository<Foo, String>{
}
@服务
类别服务1{
@自动连线
服务2服务2;
@交易的
公共无效方法1(){
Foo-Foo=新的Foo();
foo.setId(“f123”);
服务2.保存值(foo);
}
}
@服务
@事务性(隔离=隔离。读取\未提交)
类别服务2{
@自动连线
食物知识库;
公共void保存值(Foo值){
fooRepository.saveAndFlush(值);
}
}
公共接口FooRepository扩展了JpaRepository{
}
情景2:
@Service
class Service1{
@Autowired
Service2 service2;
@Transactional
public void method1(){
Foo foo=new Foo();
foo.setId("f123");
service2.saveValue(foo);
try{
updateOperation()
}catch(Throwable e){ // does Spring @Transactional revert on ERRORS, by default it rollback on RuntimeException and Exception(in case we explicitly mention)?
service2.deleteByFooId(foo.getId());
throw e;
}
}
private void updateOperation(){
/* update logic for resource */- Not a DB update
}
@Service
@Transactional(propagation=Propagation.REQUIRES_NEW)
class Service2{
@Autowired
FooRepository fooRepository;
public void saveValue(Foo value){
fooRepository.saveAndFlush(value);
}
public void delete(String id){
deleteByFooId(id);
}
}
public interface FooRepository extends JpaRepository<Foo, String>{
}
@服务
类别服务1{
@自动连线
服务2服务2;
@交易的
公共无效方法1(){
Foo-Foo=新的Foo();
foo.setId(“f123”);
服务2.保存值(foo);
试一试{
更新操作()
}catch(Throwable e){//Spring@Transactional是否会在错误时恢复,默认情况下会在RuntimeException和Exception时回滚(在我们明确提到的情况下)?
service2.deleteByFooId(foo.getId());
投掷e;
}
}
私有void updateOperation(){
/*资源*/的更新逻辑-不是数据库更新
}
@服务
@事务性(传播=传播。需要\u新建)
类别服务2{
@自动连线
食物知识库;
公共void保存值(Foo值){
fooRepository.saveAndFlush(值);
}
公共无效删除(字符串id){
deleteByFooId(id);
}
}
公共接口FooRepository扩展了JpaRepository{
}
场景2 in..Propagation Require_New..是我使用的。如果在父方法期间出现任何运行时异常,我已在try catch中处理该异常,并还原了锁,该锁作为新事务的一部分在数据库中更新,并在catch块中抛出相同的异常,以便还原父事务也是
如果您有许多dB状态需要单独还原,那么这种方法将很困难,但现在已经足够了。我使用的场景2 in..Propagation Require_New..是in..Propagation Require_New..。如果在父方法期间出现任何运行时异常,我已在try catch中处理该异常,并还原了upd锁作为新事务的一部分,在DB中初始化,并在catch块中引发相同的异常,以便父事务也被还原
如果您有许多dB状态需要单独恢复,那么这种方法将很困难,但现在就足够了。不,您不能更改正在运行的事务的隔离级别。@M.Deinum-感谢您的快速响应,请检查我的更新,并为我的使用案例提出任何解决方案(一次线程touc以粗体突出显示)他完全忽略了@Transactional,internal@Transactionals。不,您不能更改正在运行的事务的隔离级别。@M.Deinum-感谢您的快速响应,您能检查我的更新并为我的使用案例提出任何解决方案吗?一旦线程触及@Transactional,internal@Transactionals被忽略完全。