Spring-TX声明式事务控制
首先我们应该明确不管是哪种框架我们都是实现Spring通过的PlatformTransactionManager接口,这样才能把我们的数据交给Spring管理
Spring中的事物控制API介绍
PlatformTransactionManager接口
- 获取事务状态信息------------,TransactionStatus getTransaction(TransactionDifinition difinition)
- 提交事务------------ void commit(TransactionStatus status)
- 回滚事务-----------void rollback(TransactionDifinition difinition)
TransactionDifinition 事务定义信息对象
- 获取事务对象名称 String getName()
- 获取事务的隔离级别 int SgetlsolationLevel()
- 获取事务的传播行为 int getPropagationBehavior();
- 获取事务超时时间 int getTimeout();
- 获取事务是否只读 boolean idReadOnly()
TransactionStatus 事务传播行为
主要解决的就是业务方法进行调用的时候,事务应该如何进行处理
** 保证在同一事物中**
- PROPAGATION_REQUIRED 支持当前事务, 如果不存在 就新建一个(默认)事务
- PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务。
- PROPAGATION_MANDATORY 支持当前事务,如果不存在,抛出异常
保证不在同一事物中 - PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建一个新的事务
- PROPAGATION_NOT_SUPPORTED 以非事务方式运行,如果有事务存在,挂起当前事务
- PROPAGATION_NEVER 以非事务方式运 行,如果有事务存在,抛出异常
- PROPAGATION_NESTED 如果当前事务存 在,则嵌套事务执行
超时时间
如果没有设定超时时间,默认是没有超时时间限制的默认值为1 如果设置了 单位是秒
是否只读事务
对于增删改设定为 false 表示可以操作不限于只读 对于查询操作 设定为true 表示只能读
代码演示
首先写一个pojo实体类
要写成一个javaBean
@Component("user") //表示交给Spring空间管理
public class User implements Serializable {
@Value("1")//表示赋值
private Integer u_id;
@Value("小孙")//表示赋值
private String u_name;
@Value("20")//表示赋值
private Integer u_age;
@Value("10000")//表示赋值
private Double u_salary;
dao接口和他的实现类
public interface UserDao {
//CRUD
// 添加用户
void addUser(User user);
// 删除用户 根据id值
void deleteUserById(int uid);
// 修改用户信息 根据id值
void updateUserById(User user);
// 查询所有用户
List<User> queryAllUsers();
// 查询单个用户 根据id值
User queryUserById(int uid);
// 分页+模糊查询
List<User> queryFuzzyUserByUsername(String u_name,int beginIndex);
// 查询总记录值
int queryUserCount();
}
//实现类
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Autowired //前提是Spring容器含有该对象
private JdbcTemplate jdbcTemplate;
//Connection 引入数据源奥
@Autowired
private DataSource dataSource;
// 对于数据库来说 增删改 都是更新
@Override
public void addUser(User user) {
Connection connection = null;
// 在sql执行之前 开启事务
try {
//添加用户
connection = dataSource.getConnection();
//开启事务
connection.setAutoCommit(false); //设置为false 表示开启事务
PreparedStatement ps = connection.prepareStatement("insert into user values(null,?,?,?)");
ps.setString(1,user.getU_name());
ps.setInt(2,user.getU_age());
ps.setDouble(3,user.getU_salary());
int num = ps.executeUpdate();
//进行事务的提交
//int i = 1/0; //人造算数异常
connection.commit();
if (num > 0) {
System.out.println("数据添加成功!");
} else {
System.out.println("数据添加失败!");
}
} catch (Exception e) {
System.out.println("异常发生了");
try {
//有异常信息就回滚
System.out.println("因为异常,所以数据回滚");
connection.rollback();
} catch (Exception throwables) {
System.out.println("此时添加过程中有异常数据回滚.");
}
}
}
@Override
public void deleteUserById(int uid) {
int num = jdbcTemplate.update("delete from user where u_id = ?", uid);
if (num > 0) {
System.out.println("数据删除成功!");
} else {
System.out.println("数据删除失败!");
}
}
// 更新用户名和年龄
@Override
public void updateUserById(User user) {
int num = jdbcTemplate.update("update user set u_name = ?,u_age = ? where u_id = ?", user.getU_name(), user.getU_age(), user.getU_id());
if (num > 0) {
System.out.println("数据更新成功!");
} else {
System.out.println("数据更新失败");
}
}
@Override
public List<User> queryAllUsers() {
List<User> users = null;
try {
// BeanPropertyRowMapper 装配多条记录
users = jdbcTemplate.query("select * from user", new BeanPropertyRowMapper<>(User.class));
} catch (Exception e) {
e.printStackTrace();
}
return users;
}
@Override
public User queryUserById(int uid) {
// 根据用户id值查询一条记录 queryForObject方法
User user = null;
try {
user = jdbcTemplate.queryForObject("select * from user where u_id = ?", new BeanPropertyRowMapper<>(User.class), uid);
}catch (Exception e) {
e.printStackTrace();
}
return user;
}
// 分页+模糊查询
@Override
public List<User> queryFuzzyUserByUsername(String u_name, int beginIndex) {
List<User> users = null;
try {
users = jdbcTemplate.query("select * from user where u_name like '%' ? '%' limit ?,3", new BeanPropertyRowMapper<>(User.class),u_name,beginIndex);
}catch (Exception e){
e.printStackTrace();
}
return users;
}
@Override
public int queryUserCount() {
// 需要返回一个数值 queryForObject 后面传入Integer.class字节码对象
int count = jdbcTemplate.queryForObject("select count(*) from user", Integer.class);
return count;
}
}
主配置文件applicationContext.xml
<!--组件扫描--><!--能扫描到一个包里面全部的类,包下类的自动载入-->
<context:component-scan base-package="com.zhiyou100"/>
<!--content:property-->
<!--引入db.properties文件到Spring容器-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源-->
<!--采用数据库连接池 C3p0 依赖于数据源DataSource ComboPooledDataSource -->
<!--把ComboPooledDataSource该对象注入到Spring的容器中-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置JdbcTemplate对象-->
<!--该对象也依赖于数据源DataSource-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--属性注入 采用set方式--><!--后面我们使用的事dataSource-->
<property name="dataSource" ref="dataSource"/>
<!-- <constructor-arg -->
</bean>
db.properties文件和log4j.properties文件
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/db_spring?characterEncoding=UTF-8
jdbc.user=root
jdbc.password=root
# log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
测试类文件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class JdbcTemplateTest {
// 进行dao接口的属性注入
@Autowired //我们之前把 UseDaoImpl注入spring内存管理就是为了这里的属性注入@Repository("userDao")
private UserDao userDao;
@Autowired
private User user;// 此时user值就从容器注入进来
/**
* 测试 查询总记录值
*/
@Test
public void testQueryCount() {
int count = userDao.queryUserCount();
System.out.println(count);// 9
}
/**
* 测试 分页+模糊查询
*/
@Test
public void testQueryFuzzyUserByUsername() {
List<User> users = userDao.queryFuzzyUserByUsername("小", 0);
for (User user1 : users) {
System.out.println(user1);
}
}
/**
* 测试 queryUserById
*/
@Test
public void testQueryUserById() {
// 周八 id值为 7
User user = userDao.queryUserById(7);
System.out.println(user);//User{u_id=7, u_name='周八', u_age=29, u_salary=6000.0}
}
/**
* 测试 queryAllUsers
*/
@Test
public void testQueryALllUsers(){
List<User> users = userDao.queryAllUsers();
for (User user1 : users) {
System.out.println(user1);
}
}
/**
* 测试 deleteUser
*/
@Test
public void testDeleteUser() {
userDao.deleteUserById(11);// 数据删除成功!
}
/**
* 测试 updateUser
*/
@Test
public void testUpdateUser() {
// 更新用户名字和年龄 根据id值 --->把小孙的信息更改为小强的信息
User user = new User();
user.setU_age(40);
user.setU_name("小强");
user.setU_id(11);
userDao.updateUserById(user);// 数据更新成功!
}
/**
* 测试 addUser
*/
@Test
public void testAddUser(){
userDao.addUser(user);
}
}
本文详细介绍了Spring框架中的声明式事务控制,包括PlatformTransactionManager接口的使用、TransactionDifinition对象属性、事务传播行为以及实际代码演示。通过UserDao实例,展示了如何在Spring中管理事务,包括PROPAGATION_REQUIRED的事务处理和超时、只读设置。
892

被折叠的 条评论
为什么被折叠?



