编程式事务
TransactionFilter{
try{
获取连接
设置非自动提交(setAutoCommit(false))
chain.doFilter();
提交(commit)
}catch(Exception e){
回滚(rollback())
}finally{
关闭连接,释放资源
}
}
声明式事务
以前通过复杂的编程来编写一个事务,替换为只需要告诉spring哪个方法是事务方法即可
spring自动进行事务控制
AOP:环绕通知可以去做
获取连接
设置非自动提交
目标代码执行
正常提价
异常回滚
最终关闭
事务管理代码的固定模式作为一种横切关注点,可以通过AOP方法模块化,进而借助spring AOP 框架实现什么式事务管理
快速的为某个方法添加事务
<!--事务控制-->
<bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制数据源-->
<constructor-arg ref="dataSource"/>
</bean>
<!--开启基于注解的事务控制模式,依赖tx名称空间-->
<tx:annotation-driven transaction-manager="manager"/>
<!--给事务方法加注解 @Transactional-->
@Transactional
public void checkout(String username, String isbn) {
bookDao.updateStock(isbn);
int price = bookDao.getPrice(isbn);
bookDao.updateBanlance(username, price);
}
JdbcTemplate
package com.jxau;
import com.jxau.bean.Emp;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.ArrayList;
import java.util.List;
public class test {
private ApplicationContext ioc = new ClassPathXmlApplicationContext("ApplicationContext.xml");
private JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);
//获取连接
@Test
public void test1() {
ComboPooledDataSource dataSource = ioc.getBean(ComboPooledDataSource.class);
System.out.println(dataSource);
}
//更新数据
@Test
public void test2() {
String sql = "update salarys set age=? where id=?";
jdbcTemplate.update(sql,100, 1);
System.out.println("yes");
}
//插入多条数据
@Test
public void test3() {
String sql = "insert into salarys value(default, ?, ?, ?)";
List<Object[]> alist = new ArrayList<Object[]>();
alist.add(new Object[]{"lisi1", 1, 1999});
alist.add(new Object[]{"lisi2", 2, 2999});
alist.add(new Object[]{"lisi3", 3, 3999});
alist.add(new Object[]{"lisi4", 4, 4999});
int[] ints = jdbcTemplate.batchUpdate(sql, alist);
System.out.println(ints.length);
}
/**
* 查询数据库记录,封装成java对象返回
* Javabean需要和数据库中字段名一致,否则无法完成封装
* JdbcTemplate在方法级别进行了区分
* 查询集合:query 如果查询没结果就报错
* 查询单个对象:queryForObject
*
*/
//查询单条数据
@Test
public void test4() {
String sql = "select * from salarys where id=?";
Emp emp = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Emp>(Emp.class), 1);
System.out.println(emp);
}
//查询多条数据,并封装成list集合
@Test
public void test5() {
String sql = "select * from salarys where salary=?";
List<Emp> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class), 1000);
for (Emp i : query) {
System.out.println(i);
}
}
//聚合函数的使用,并获取其返回值
@Test
public void test6() {
String sql = "select max(salary) from salarys";
Double aDouble = jdbcTemplate.queryForObject(sql, Double.class);
System.out.println(aDouble);
}
}
事务细节
isolation-Isolation 事务的隔离级别(详见数据库笔记)
propagation-Propagation 事务的传播行为
required:将之前事务用的connection传递给这个方法使用
requires_new:这个方法直接使用新的connection
noRollbackFor-Class[] 哪些异常事务可以不回滚
noRollbackForClassName-String[] (String全类名)
异常分类:
运行时异常(非检查异常),可以不用处理,默认都回滚
编译时异常(检查异常):要么try-catch,要么在方法上声明throws, 默认不回滚
rollbackFor-Class[] 哪些异常事务需要回滚
rollbackForClassNmae-String[]
teadOnly-boolean 设置事务为只读事务
timeout-int 超时:事务超出指定执行时长后自动终止并回滚