1.准备数据库:
2.导入操作数据库相关的jar包:
3.配置数据源和JDBCTemplate类:
<context:component-scan base-package="com.hh"/>
<!--配置数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"/>
<property name="password" value="123"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jdbc_template"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
</bean>
<!--Spring提供了一个类JDBCTemplate,用它来操作数据库-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg name="dataSource" ref="dataSource"/>
</bean>
4.在dao层写一个类,里面有三个方法:减余额,获取价格,减库存的操作
@Repository
public class BookDao {
@Autowired
JdbcTemplate jdbcTemplate;
//减去某个用户的余额
public void updateBalance(String userName,int price){
String sql = "update account set balance=balance-? where userName=?";
jdbcTemplate.update(sql,price,userName);
}
//获取某本图书的价格
public int getPrice(String isbn){
String sql = "select price from book where isbn=?";
return jdbcTemplate.queryForObject(sql,Integer.class,isbn);
}
//减库存:减去某本书的库存
public void updateStock(String isbn){
String sql = "update book_stock set stock=stock-1 where isbn=?";
jdbcTemplate.update(sql,isbn);
}
}
5.在service层写一个类,用来调用这些dao层的方法
@Service
public class BookService {
@Autowired
BookDao bookDao;
//传入哪个用户买了哪本书
public void checkout(String username,String isbn){
//减库存
bookDao.updateStock(isbn);
//获取价格
int price = bookDao.getPrice(isbn);
//减价格
bookDao.updateBalance(username,price);
}
}
6.测试类:
public class MyTest {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
@Test
public void test(){
BookService bookService = context.getBean(BookService.class);
bookService.checkout("Tom","ISBN-001");
}
}
声明式事务:AOP
在目标方法前后加入通知方法,并且Spring提供了切面(事务管理器),这个事务管理器就可以在目标方法运行的时候进行事务控制,目前使用的事务管理器为DataSourceTransactionManager
获取连接
设置非自动提交
目标代码执行
正常提交
异常回滚
最终关闭
快速的为某个方法添加事务:
(1)配置事务管理器DataSourceTransactionManager
<!--配置事务管理器让我进行事务控制-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
(2)开启基于注解的事务控制模式
<!--开启基于注解的事务控制模式:依赖tx名称空间-->
<tx:annotation-driven transaction-manager="transactionManager"/>
(3)给事务方法加注解@Transactional
@Transactional
public void checkout(String username,String isbn){
//减库存
bookDao.updateStock(isbn);
//获取价格
int price = bookDao.getPrice(isbn);
//减价格
bookDao.updateBalance(username,price);
}
测试类:
public class MyTest {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
@Test
public void test(){
BookService bookService = context.getBean(BookService.class);
bookService.checkout("Tom","ISBN-001");
}
}
同时成功:
现在余额的sql语句故意写错:
//减去某个用户的余额
public void updateBalance(String userName,int price){
String sql = "updateeee account set balance=balance-? where userName=?";
jdbcTemplate.update(sql,price,userName);
}
再次加入事务,测试,看测试结果:
同时失败