1、 四大特性:【ACID】
① 原子性(atomicity):不可分割,表现为一个事务中涉及到的多个操作在逻辑上缺一不可,要求事务中的所有操作要么都执行,要么都不执行
② 一致性(consistency):数据一致,所有数据都处于满足业务规则的一致性状态。一个事务不管涉及到多少个操作,都必须保证事务执行前后数据都是正确的;如果有一个或某几个操作失败了,则必须将其他所有的操作撤销,将数据恢复到事务执行前的状态,也就是说回滚
③ 隔离性(isolation):要求多个事务在并发执行过程中不会相互干扰
④ 持久性(durability):事务执行完成后,对数据的修改永久的保存下来,被写入到持久化存储器中不会因各种系统错误或其他意外情况而受到影响
2、三种行为:
① 开启事务:connection.setAutoCommit(flase)
② 提交事务:connection.commit()
③ 回滚事务:connection.rollback()
3、 编程式事务管理:
1) 获取数据库连接Connection对象
2) 取消事务的自动提交
3) 执行操作
4) 正常完成操作时手动提交事务
5) 执行失败时回滚事务
6) 关闭相关资源
总结:编程式事务管理不足,将事务管理代码【非业务代码】与业务代码书写一处,导致代码混乱和代码分散问题。
此时:需要使用AOP思想【先横向提取,再动态织入】,管理事务:声明式事务管理
4、声明式事务管理:
1)导入相关jar包
spring-aspects-5.3.1.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar <依赖上jar包>
2)开启声明式事务管理支持
3)在需要事务管理的方法或类上,添加@Transactional
5、不使用事务管理问题
案例:以买书为例
public void purchase(String userId, String isbn) {
//1.查询book价格
Integer price = bookShopDao.getBookPriceByIsbn(isbn);
//2.修改库存
bookShopDao.updateBookStock(isbn);
//3.修改余额
bookShopDao.updateUserBalance(userId,price);
}
@Test
public void testBookShopService(){
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext_transaction.xml");
BookShopServiceImpl bookShopService = context.getBean("bookShopService", BookShopServiceImpl.class);
bookShopService.purchase("101","1002");
}
purchase() 方法中三个步骤,应该使用事务管理;如果不使用事务管理,可能会出现【修改库存,但未修改余额】问题
6、使用事务管理
1)导入jar包
org.springframework
spring-aspects
5.3.1
2)开启声明事务管理支持
3)在需要事务管理的方法或类上,添加@Transactional
@Transactional
public void purchase(String userId, String isbn) {
//1.查询book价格
Integer price = bookShopDao.getBookPriceByIsbn(isbn);
//2.修改库存
bookShopDao.updateBookStock(isbn);
//3.修改余额
bookShopDao.updateUserBalance(userId,price);
}
@Test
public void testBookShopService(){
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext_transaction.xml");
//事务声明式事务管理【不能使用BookShopServiceImpl接收,原因代码对象与目标对象是兄弟关系】
//BookShopServiceImpl bookShopService = context.getBean("bookShopService", BookShopServiceImpl.class);
BookShopService bookShopService = context.getBean("bookShopService", BookShopService.class);
bookShopService.purchase("101","1001");
}
7、声明式事务管理中的属性
1)事务传播行为 :当事务方法被另一个方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务中运行。
语法:(propagation = Propagation.REQUIRED)默认
2)事务隔离级别:一个事务与其他事务隔离的程度称为隔离级别
语法:(isolation = Isolation.REPEATABLE_READ)
<1>数据库ation=)事务并发问题
①脏读:读到了别人更新但未提交的数据
②不可重复读:两次读取的值不可重复
③幻读:两次读取的表中的记录不一样,好像出现幻觉一样
<2>隔离级别 MYSQL查询隔离等级语句:show variables like 'tx_isolation'
①读未提交:READ UNCOMMITTED 【1】
②读已提交:READ COMMITTED 【2】
③可重复读:REPEATABLE READ 【4】
④串行化:SERIALIZABLE 【8】
3) 事务超时 : timeout 可以设置事务在强制回滚之前可以保持多久,防止长期运行的事务占领资源并对整体性能产生影响
4) 事务只读:readaonly 可以设置事务只读数据不做修改,帮助数据库引擎优化事务
5) 事务异常回滚[不回滚]
rollbackFor或rollbackForClassName属性:指定遇到时必须进行回滚的异常类型,可以为多个。
noRollbackFor或noRollbackForClassName属性:指定遇到时不回滚的异常类型,可以为多个
二、Spring中的JdbcTemplate框架1、JdbcTemplate简介
-
JdbcTemplate是持久化层框架【类似:Mybatis】
2 、搭建JdbcTemplate步骤
-
导入相关jar包
org.springframework spring-context5.3.1 org.springframework spring-jdbc5.3.1 org.springframework spring-orm5.3.1 org.projectlombok lombok1.18.12 compile -
编写核心配置文件
- 装配JdbcTemplate
-
使用JdbcTemplate相应方法
3、 JdbcTemplate常用API
-
update(String sql,Object... params) 增删改通用方
-
batchUpdate(String sql,List
- queryForObject()
-
queryForObject(String sql,Class clazz,Object... params)
-
查询单个数值:select count(1) from table
-
-
queryForObject(String sql,RowMapper
mapper,Object... params) -
查询单个对象:select col1,col2 ... from table where id=?
-
-
- queryForObject()
-
query(String sql,RowMapper
mapper,Object... params) -
查询多个对象,通用方法
-
1、Spring5整合Log4j2
①导入jar包
org.apache.logging.log4j log4j-slf4j-impl2.11.2 test
② 配置文件
2、spring整合JUnit5
导入jar包
Spring5的测试包 :spring-test-5.3.1.jar
Junit5相关jar包 :apiguardian-api-1.1.0.jar ;junit-jupiter-api-5.7.0.jar ;
junit-platform-commons-1.7.0.jar ; opentest4j-1.2.0.jar
org.springframework spring-test5.3.1 org.junit.jupiter junit-jupiter-api5.7.2 test
使用@ExtendWith注解和@ContextConfiguration注解
使用符合注解@SpringJUnitConfig
//@ExtendWith(SpringExtension.class)
//@ContextConfiguration(locations = "classpath:applicationContext_transaction.xml")
@SpringJUnitConfig(locations = "classpath:applicationContext_transaction.xml")
public class TestJunit5 {
@Autowired
private BookShopDao bookShopDao;
@Test
public void testJunit5(){
Integer bookPriceByIsbn = bookShopDao.getBookPriceByIsbn("1001");
System.out.println("bookPriceByIsbn = " + bookPriceByIsbn);
}
}



