一、事物操作(事物概念)
1、事物
事物是数据库操作最基本单元,逻辑上一组操作,要么成功,如果有一个失败所有操作都失败
2、场景举例
例如:银行转账
(1)Luck转账给100元给mary
(2)lucy—100元,mary+100元
3、事物四个特性(ACID)
(1)原子性(Atomicity)
原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。
(2)一致性(Consistency)
一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账、转几次账,事务结束后两个用户的钱相加起来应该还得是1000,这就是事务的一致性。
(3)隔离性(Isolation)
隔离性是当多个用户并发访问数据库时,比如同时操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到。
(4)持久性(Durability)
持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务已经正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成。否则的话就会造成我们虽然看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。这是不允许的。
二、事物操作(搭建实务操作环境)
1、创建数据库表,添加记录
2、创建service,搭建dao,完成对象创建和注入关系
(1)service注入dao,在dao注入JdbcTemplate,在JdbcTemplate注入DataSource
@Service
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
}
@Repository
public class UserDaoImpl {
@Autowired
private JdbcTemplate jdbcTemplate;
}
3、在dao创建两个方法:多钱和少钱的方法,在service创建方法(转账的方法)
//luck转账给mary UserDaoImpl类中
//多钱
@Override
public void addMoney() {
String sql = "update t_account set money=money+? where username=?";
jdbcTemplate.update(sql, 100,"lucy");
}
//少钱
@Override
public void reduceMoney() {
String sql = "update t_account set money=money-? where username=?";
jdbcTemplate.update(sql, 100,"lucy");
}
@Service
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//转账的方法
public void acountMoney(){
//mary多100
userDao.addMoney();
//lucy少100
userDao.reduceMoney();
}
}
测试代码
@Test
public void testJdbacTemplate(){
ApplicationContext context=
new ClassPathXmlApplicationContext("bean1.xml");
UserService userService =context.getBean("userService", UserService.class);
userService.acountMoney();
4、上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,有问题。
@Service
public class UserService {
//注入dao
@Autowired
private UserDao userDao;
//转账的方法
public void acountMoney(){
//mary多100
userDao.addMoney();
//模拟异常
int i =10/0;
//lucy少100
userDao.reduceMoney();
}
}
(1)上面问题如何解决,使用事物进行解决
(2)事务操作过程
//转账的方法
public void acountMoney(){
try {
//第一步 开启事物
//第二部 进行业务操作
//mary多100
userDao.addMoney();
//模拟异常
//lucy少100
userDao.reduceMoney();
//第三步 没有发生异常,提交事务
}catch (Exception e){
//第四步 出现异常,事物回滚
}
}
三、事务操作(Spring事务管理介绍)
1、事物添加到JavaEE三层结构里面Service层(业务逻辑层)
2、在Spring进行事物管理操作
(1)有两种方式:编程式事务管理(例如上面代码)和声明式事务管理(使用)
3、声明式事务管理
(1)基于注解方式
(2)基于xml配置文件方式
4、在Spring进行声明式事务管理,底层使用AOP原理
5、Spring事务管理API
(1)提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类。
三、事务操作(注解声明式事务管理)
1、在spring配置文件中配置事务管理器
2、在spring配置文件,开始事务注解
(1)在spring配置文件引入名称空间tx
(2)开启事物的注解
3、在service类上面(获取service类里面方法上面)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可添加方法上面
(2)如果把这个注解添加到类上面,这个类里面所有的方法都添加事物
(3)如果把这个注解添加到方法上面,为这个方法添加事物
@Service
@Transactional
public class UserService {
四、事务操作(声明式事务管理参数配置)
1、在service类上面添加注解@Transactional,在这个注解里面可以配置事物
2、propagation:事务传播行为
(1)多事物方法直接进行调用,这个过程中事物是如何进行管理的
@Service
@Transactional(propagation = Propagation.REQUIRED)
public class UserService {
3、ioslation:事务隔离级别
(1)事物有一个特性称为隔离性,多事务操作之间不会产生影响。不考虑隔离性产生很多问题
(2)有三个读问题:脏读、不可重复性、虚(幻)读
①脏读:一个未交事物读取到另一个未提交事物的数据
②不可重复读:一个未交事物读取到另一个提交事物修改的数据
③虚(幻)读:一个未交事物读取到另一个提交事物添加的数据
(3)解决:通过设置事物隔离级别,解决读问题
@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)
public class UserService {
4、timeout:超时时间
(1)事物需要在一定时间内进行提交,如果不提交进行回滚
(2)默认值-1,设置时间以秒为单位进行计算
5、readOnly:是否只读
(1)读:查询操作,写:添加修改删除操作。
(2)readOnly默认值是false,表示可以查询,可以添加修改删除操作
(3)设置readOnly值是true,设置成true之后,只能查询
6、rollbackFor:回滚
(1)设置查询那些异常进行事物回滚
7、noRollbackFor:不回滚
(1)设置出现那些异常不进行事物回滚
五、事务操作(XML声明式事务管理)
1、在spring配置文件中进行配置
(1)配置事务管理器
(2)配置通知
(3)配置切入点和切面
六、事务操作(完全注解声明式事务管理)
@Configuration //配置类
@ComponentScan(basePackages = "com.oykq") //组件扫描
@EnableTransactionManagement //开启事物
public class config {
//创建数据库连接池
@Bean
public DruidDataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///user_db");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
//创建JdbcTemplate对象
@Bean
public JdbcTemplate getJdbcTemplate(DataSource dataSource){
//到ioc容器中根据类型找到dataSource
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//注入dataSource
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
//创建事务管理器
@Bean
public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource){
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}
}
测试代码
@Test
public void testJdbacTemplate2(){
ApplicationContext context=
new AnnotationConfigApplicationContext(config.class);
UserService userService =context.getBean("userService", UserService.class);
userService.acountMoney();
}



