spring @Transactional 聲明式事務


項目地址:git@github.com:witaste/transaction-annotation.git

情景一:

A external method calls a method of the target object 

外部方法調用目標對象的事務方法,異常逐層拋出,最終由a() 拋出,可以回滾。

@Service
public class FooServiceImpl implements FooService {

    @Autowired
    private FooMapper fooMapper;

    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
        b();
    }

    public void b() {
        fooMapper.insert(new Foo("1"));
        int i = 1 / 0;
        fooMapper.insert(new Foo("2"));
    }
}

 

情景二:

The target object call another method of the target object  

不能開啟事務,插入了一條數據。

@Service
public class FooServiceImpl implements FooService {

    @Autowired
    private FooMapper fooMapper;

    public void a() {
        try {
            b();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void b() {
        fooMapper.insert(new Foo("1"));
        int i = 1 / 0;
        fooMapper.insert(new Foo("2"));
    }
}

 

情景二解決辦法:

辦法1.

將b() 轉移到OtServiceImpl 中即可。

辦法2.

使用代理對象調用b() , 即:

((FooService) AopContext.currentProxy()).b();

需要引入jar包

        <!-- aspectj -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>

需要暴露代理:

<aop:aspectj-autoproxy expose-proxy="true"/>

修改后的類:

@Service
public class FooServiceImpl implements FooService {

    @Autowired
    private FooMapper fooMapper;

    public void a() {
        try{
            ((FooService) AopContext.currentProxy()).b();
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void b() {
        fooMapper.insert(new Foo("1"));
        int i = 1 / 0;
        fooMapper.insert(new Foo("2"));
    }
}

PS:其他復雜情景不做考慮

 

官方文檔:http://docs.spring.io/spring/docs/4.2.0.RC1/spring-framework-reference/htmlsingle/#transaction-declarative-annotations

附運行日志:

情景一: 

16:02:27.372 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:02:27.372 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.403 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will be managed by Spring
16:02:27.403 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:02:27.403 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==>  Preparing: select sys_guid() from dual 
16:02:27.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters: 
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ==>  Preparing: insert into FOO (ID, NAME) values (?, ?) 
16:02:27.872 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220CFD8EE4A60CF3E053433210AC3DFB(String), 1(String)
16:02:27.903 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.950 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:02:27.950 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]

 

情景二:

16:09:12.544 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:09:12.544 [main] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@db15e1] was not registered for synchronization because synchronization is not active
16:09:12.622 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will not be managed by Spring
16:09:12.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:09:12.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==>  Preparing: select sys_guid() from dual 
16:09:12.732 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters: 
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [24683438, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ==>  Preparing: insert into FOO (ID, NAME) values (?, ?) 
16:09:12.794 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220D15B5E3891024E053433210AC7FE0(String), 1(String)
16:09:12.841 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@db15e1]
/ by zero

 

情景二改:

16:12:13.466 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
16:12:13.482 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.513 [main] DEBUG o.m.s.t.SpringManagedTransaction - JDBC Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver] will be managed by Spring
16:12:13.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:12:13.513 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==>  Preparing: select sys_guid() from dual 
16:12:13.622 [main] DEBUG c.zno.dao.FooMapper.insert!selectKey - ==> Parameters: 
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ooo Using Connection [33362707, URL=jdbc:oracle:thin:@//172.16.50.67:1521/orcl, UserName=E_CHANNEL, Oracle JDBC driver]
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ==>  Preparing: insert into FOO (ID, NAME) values (?, ?) 
16:12:13.685 [main] DEBUG cn.zno.dao.FooMapper.insert - ==> Parameters: 220D207E0A56111CE053433210ACAD95(String), 1(String)
16:12:13.716 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.747 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization rolling back SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
16:12:13.747 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@14d3d6d]
/ by zero

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM