UserServiceImpl就可以看做是A事务
AccountServiceImpl就可以看做是B事务
项目中的所有事务,必须添加到业务逻辑上。
若A事务要包含进B事务,怎么包含?
UsersServiceImpl.java
@AutowiredAccountService accountService;
@Overridepublic int insertUsers(Users users) {// return usersMapper.insertUsers(users);int num = usersMapper.insertUsers(users);System.out.println(num);//调用账户的增加操作,调用的账户的业务逻辑层的功能num = accountService.insertAccount(new Account(300,"王五","账户好的呢"));return num;}
事务传播特性解析(重点)
| UsersServiceImpl | AccountServiceImpl(抛异常) | 预测结果 | |
|---|---|---|---|
| 场景一 | 无事务 | 无事务 | users=OK;account=OK |
| 场景二 | 无事务 | REQUIRED | users=OK;account=NO |
| 场景三 | REQUIRED | 无事务 | users=NO;account=NO |
| 场景四 | REQUIRED | NOT_SUPPORTED | users=NO;account=OK |
| 场景五 | REQUIRED | SUPPORTS | users=NO;account=NO |
| 场景六 | REQUIRED | REQUIRES_NEW | users=NO;account=NO |
| 场景七 | REQUIRED | REQUIRED | users=NO;account=NO |
| 场景八 | REQUIRED | NEVER | users=NO;account=NO |
#清空表中数据USE ssm;DELETE FROM users;DELETE FROM accounts;
场景一
@Testpublic void testUsers(){//创建容器并启动ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext_service.xml");//取出UsersServiceImpl(永远是接口接(干活))UsersService uService = (UsersService) ac.getBean("usersServiceImpl");int num = uService.insertUsers(new Users(1,"张三","123"));System.out.println(num);}
1添加用户成功,num=1java.lang.ArithmeticException: / by zero
查看表
users
| userid | uname | upass |
|---|---|---|
| 1 | 张三 | 123 |
accounts
| aid | aname | acountent |
|---|---|---|
| 300 | 王五 | 账户好的呢 |
场景二
AccountServiceImpl.java
package com.chentianyu.service.impl;import com.chentianyu.mapper.AccountMapper;import com.chentianyu.pojo.Account;import com.chentianyu.service.AccountService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;@Service@Transactional(propagation = Propagation.REQUIRED)/*REQUIRED传播特性*/public class AccountServiceImpl implements AccountService {//但凡是业务逻辑层的实现类,一定会有数据访问层的对象@AutowiredAccountMapper accountMapper;@Overridepublic int insertAccount(Account account) {int num = 0;num = accountMapper.insertAccount(account);System.out.println("添加用户成功,num="+num);//手动抛出异常System.out.println(1/0);//出现错误的时候我们不希望数据插入进数据库return num;}}
为了查看方便,mybatis主配置文件添加
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings></configuration>
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4a9cc6cb] will not be managed by Spring==> Preparing: insert into users values(?,?,?)==> Parameters: 1(Integer), 张三(String), 123(String)<== Updates: 1Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1698fc68]1Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5149f008]JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4a9cc6cb] will be managed by Spring==> Preparing: insert into accounts values(?,?,?)==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)<== Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5149f008]添加用户成功,num=1
字面上看是增加成功的
我们看一下数据库中的数据
users
| userid | uname | upass |
|---|---|---|
| 1 | 张三 | 123 |
accounts(有事务)
| aid | aname | acountent |
|---|---|---|
场景三
UsersServiceImpl.java
@Service //交给spring去创建对象@Transactional(propagation = Propagation.REQUIRED)public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Servicepublic class AccountServiceImpl implements AccountService {...}
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7a56812e] will be managed by Spring==> Preparing: insert into users values(?,?,?)==> Parameters: 1(Integer), 张三(String), 123(String)<== Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]1Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605] from current transaction==> Preparing: insert into accounts values(?,?,?)==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)<== Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]添加用户成功,num=1Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@48c40605]java.lang.ArithmeticException: / by zero
貌似都添加成功了
users(有事务)
| userid | uname | upass |
|---|---|---|
accounts
| aid | aname | acountent |
|---|---|---|
accounts外层(users)有事务,被合并到外边的事务中了,所以也裹上了事务的处理
场景四
UsersServiceImpl.java
@Service //交给spring去创建对象@Transactional(propagation = Propagation.REQUIRED)public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Service@Transactional(propagation = Propagation.NOT_SUPPORTED)public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring==> Preparing: insert into users values(?,?,?)==> Parameters: 1(Integer), 张三(String), 123(String)<== Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]1Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]Creating a new SqlSessionRegistering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring==> Preparing: insert into accounts values(?,?,?)==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)<== Updates: 1Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]添加用户成功,num=1Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]java.lang.ArithmeticException: / by zero
貌似都添加成功了
users
| userid | uname | upass |
|---|---|---|
accounts
| aid | aname | acountent |
|---|---|---|
| 300 | 王五 | 账户好的呢 |
场景五
UsersServiceImpl.java
@Service //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Service
@Transactional(propagation = Propagation.SUPPORTS)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==> Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==> Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
java.lang.ArithmeticException: / by zero
貌似都添加成功了
users(有事务)
| userid | uname | upass |
|---|---|---|
accounts(跟前面的保持一致,”你说的都对,都听你的”)
| aid | aname | acountent |
|---|---|---|
场景六
UsersServiceImpl.java
@Service //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==> Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==> Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
java.lang.ArithmeticException: / by zero
貌似都添加成功了
users(有事务)
| userid | uname | upass |
|---|---|---|
accounts(运行的机制不一样,但是你是包在事务中的;一出错立马回滚)
| aid | aname | acountent |
|---|---|---|
场景七
UsersServiceImpl.java
@Service //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==> Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4fbdc0f0] will be managed by Spring
==> Preparing: insert into accounts values(?,?,?)
==> Parameters: 300(Integer), 王五(String), 账户好的呢(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
添加用户成功,num=1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2970a5bc]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
java.lang.ArithmeticException: / by zero
貌似都添加成功了
users(有事务)
| userid | uname | upass |
|---|---|---|
accounts
| aid | aname | acountent |
|---|---|---|
场景八
UsersServiceImpl.java
@Service //交给spring去创建对象
@Transactional(propagation = Propagation.REQUIRED)
public class UsersServiceImpl implements UsersService {...}
AccountServiceImpl.java
@Service
@Transactional(propagation = Propagation.NEVER)
public class AccountServiceImpl implements AccountService {...}
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f4854d6] will be managed by Spring
==> Preparing: insert into users values(?,?,?)
==> Parameters: 1(Integer), 张三(String), 123(String)
<== Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
1
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@476aac9]
org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
NEVER: 你不能把我包在事务里,你敢,我就让程序崩溃
