4.事务 Transaction
4.1 概念
在进行一组 dml 语句操作 要求这组sql语句同时成功 或者 同时失败
4.2 事务的特性
原子性:事务中的语句是一个逻辑整体 必须同时成功 或者同时失败
一致性: 数据一旦变化 提交之后 就不会轻易改变
持久性:
隔离性: 解决的是数据库中的三大读问题
脏读 ----- 一个事务读取到了另外一个事务中 没有提交的数据
不可重复读 ---- 一个事务在开始时 查询一个数据 在这个事务执行的过程中 另外一个事务 对这份数据进行了更改 并进行了提交
在第一个事务中前后读取的数据就不同了 这叫不可重复读。
幻读 ---- 不可重复读关键是更改 幻读问题关注的增删
隔离性这里 对应四个隔离级别 读未提交 读提交 可重复读 序列化
4.3 jdbc 中的事务控制如何实现
conn.setAutoCommit(false);
在合适的地方进行 conn.commit();
在出问题的地方 进行 conn.rollback();
4.4 Spring 编程式 事务
@Test
public void testTransactionTemplate(){
jdbcTemplate = new JdbcTemplate(dataSource);
//构造函数初始化TransactionTemplate
TransactionTemplate template = new TransactionTemplate(txManager);
template.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
//重写execute方法实现事务管理
template.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 在这里完成事务控制
String sql = "insert into ....";
int f1 = jdbcTemplate.update(sql);
String sql2 = "update ...";
int f2 = jdbcTemplate.update(sql2);
}}
);
}
4.5 声明式事务
AOP (切面 ------ 通知------- 切点 )
1.可以通过配置形式 将操作纳入到事务管理中
之前只能硬编码来处理事务 现在可以用更加灵活的配置方式
2.代码逻辑 和 事务控制 可以松耦合
要去掉事务控制代码 可以在配置文件中进行移除
4.6 声明式事务的编程步骤
1.建立一个项目 为了完成转账(进钱 和 出钱)
2.拷贝 ioc aop dao 连接池 驱动包
3.拷贝配置文件
开启组件扫描 和 声明式事务
<context:component-scan base-package="" />
<tx:annotation-driven transaction-manager="事务管理器" proxy-target-class="" />
transaction-manager 事务管理器 需要我们在容器中自己定义
proxy-target-class 代理类是否优先使用 CGLIB sun公司有JDK的代理 这里要求 被代理类
必须实现一个接口 true 代表优先使用CGLIB
4.配置一个事务管理器
这个事务管理器 会使用到 dataSource 这个dataSource 可以被JdbcDaoSupport的子类 或者
JdbcTemplate
5.在需要事务的方法上 加 @Transactional
4.7 对 @Transactional 的说明
@Transactional 默认只对 运行时异常进行回滚 对检查异常不回滚
可以通过 rollbackFor 属性进行设置 可以针对检查异常进行回滚 如 rollbackFor={BankAccountException.class}
noRollbackFor 针对的是运行时异常
readOnly 只读 是否通过事务更新数据 如果事务中有dml 则必须readOnly是false
isolation 设置隔离级别 这是一个枚举值 Isolation.具体的四个值
propagation 事务传播特性 (了解)
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
4.1 概念
在进行一组 dml 语句操作 要求这组sql语句同时成功 或者 同时失败
4.2 事务的特性
原子性:事务中的语句是一个逻辑整体 必须同时成功 或者同时失败
一致性: 数据一旦变化 提交之后 就不会轻易改变
持久性:
隔离性: 解决的是数据库中的三大读问题
脏读 ----- 一个事务读取到了另外一个事务中 没有提交的数据
不可重复读 ---- 一个事务在开始时 查询一个数据 在这个事务执行的过程中 另外一个事务 对这份数据进行了更改 并进行了提交
在第一个事务中前后读取的数据就不同了 这叫不可重复读。
幻读 ---- 不可重复读关键是更改 幻读问题关注的增删
隔离性这里 对应四个隔离级别 读未提交 读提交 可重复读 序列化
4.3 jdbc 中的事务控制如何实现
conn.setAutoCommit(false);
在合适的地方进行 conn.commit();
在出问题的地方 进行 conn.rollback();
4.4 Spring 编程式 事务
@Test
public void testTransactionTemplate(){
jdbcTemplate = new JdbcTemplate(dataSource);
//构造函数初始化TransactionTemplate
TransactionTemplate template = new TransactionTemplate(txManager);
template.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
//重写execute方法实现事务管理
template.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 在这里完成事务控制
String sql = "insert into ....";
int f1 = jdbcTemplate.update(sql);
String sql2 = "update ...";
int f2 = jdbcTemplate.update(sql2);
}}
);
}
4.5 声明式事务
AOP (切面 ------ 通知------- 切点 )
1.可以通过配置形式 将操作纳入到事务管理中
之前只能硬编码来处理事务 现在可以用更加灵活的配置方式
2.代码逻辑 和 事务控制 可以松耦合
要去掉事务控制代码 可以在配置文件中进行移除
4.6 声明式事务的编程步骤
1.建立一个项目 为了完成转账(进钱 和 出钱)
2.拷贝 ioc aop dao 连接池 驱动包
3.拷贝配置文件
开启组件扫描 和 声明式事务
<context:component-scan base-package="" />
<tx:annotation-driven transaction-manager="事务管理器" proxy-target-class="" />
transaction-manager 事务管理器 需要我们在容器中自己定义
proxy-target-class 代理类是否优先使用 CGLIB sun公司有JDK的代理 这里要求 被代理类
必须实现一个接口 true 代表优先使用CGLIB
4.配置一个事务管理器
这个事务管理器 会使用到 dataSource 这个dataSource 可以被JdbcDaoSupport的子类 或者
JdbcTemplate
5.在需要事务的方法上 加 @Transactional
4.7 对 @Transactional 的说明
@Transactional 默认只对 运行时异常进行回滚 对检查异常不回滚
可以通过 rollbackFor 属性进行设置 可以针对检查异常进行回滚 如 rollbackFor={BankAccountException.class}
noRollbackFor 针对的是运行时异常
readOnly 只读 是否通过事务更新数据 如果事务中有dml 则必须readOnly是false
isolation 设置隔离级别 这是一个枚举值 Isolation.具体的四个值
propagation 事务传播特性 (了解)
PROPAGATION_REQUIRED
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY
使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。