标签:ice user 存储 sleep 资源 use rom actor ext
<!--1、配置连接池 --> <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="root"></property> <property name="password" value="123456"></property> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/tx"></property> </bean> <!--2、数据库的增删改查 JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!--配置事务切面;控制住连接池 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!--开启基于注解的事务功能;依赖tx名称空间 transaction-manager:指定事务管理器是哪个 --> <tx:annotation-driven/>
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; /** * [1]根据isbn的值查询书的价格, public int getPrice(String isbn); [2]根据isbn的值减少书的库存,假设每次都只买1本书, public void updateStock(String isbn); [3]根据用户名减少用户账户中的余额,减少的额度就是书的价格 public void updateBalance(int price,String user); * @author lfy * */ @Repository public class BookDao { @Autowired JdbcTemplate jdbcTemplate; /** * [1]根据isbn的值查询书的价格, * public int getPrice(String isbn); * 操作:book */ public int getPrice(String isbn){ String sql = "select price from book where isbn=?"; Integer price = jdbcTemplate.queryForObject(sql, Integer.class, isbn); return price; }; /** * [2]根据isbn的值减少书的库存,假设每次都只买1本书, * public void updateStock(String isbn); * 操作:book_stock */ public void updateStock(String isbn){ String sql = "UPDATE book_stock SET stock=stock-1 WHERE isbn=?"; jdbcTemplate.update(sql, isbn); } /** * [3]根据用户名减少用户账户中的余额,减少的额度就是书的价格 * public void updateBalance(int price,String user); * 给用户减余额;account * String user:要减余额的用户名 * int price:要减掉多少(减少的额度就是书的价格) */ public void updateBalance(int price,String user){ String sql = "update account set balance = balance-? where username=?"; jdbcTemplate.update(sql, price,user); } public void updatePrice(String isbn){ String sql = "update book set price = 999 WHERE isbn=?"; jdbcTemplate.update(sql, isbn); } }
事务注解主要添加在Service层,通过Aop来实现事务操作:
import java.io.FileInputStream; import java.io.FileNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.atguigu.dao.BookDao; @Service public class BookService { @Autowired BookDao bookDao; @Transactional(noRollbackFor=ArithmeticException.class, timeout=3,propagation=Propagation.REQUIRES_NEW) public void checkout(String username,String isbn){ //0、查出图书价格 int price = bookDao.getPrice(isbn); //1、减用户余额 bookDao.updateBalance(price, username); //2、减图书的库存 bookDao.updateStock(isbn); //Thread.sleep(3000); //new FileInputStream("D://ahahahah//aa.txt"); System.out.println("结账完成...."); } @Transactional(propagation=Propagation.REQUIRED,timeout=3) public void updatePrice(String isbn){ try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } bookDao.updatePrice(isbn); } }
propagation:事务的传播行为;我们可以通过控制指定大事务和小事务的关系;
传播(共用一个事务的情况下大事务的属性配置会传播给小事务)+行为(是否共用一个事务)。
本质上一个再读,一个在改;
数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。
①读未提交:READ UNCOMMITTED
允许Transaction01读取Transaction02未提交的修改。
②读已提交:READ COMMITTED
要求Transaction01只能读取Transaction02已提交的修改。
③可重复读:REPEATABLE READ
确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。
④串行化:SERIALIZABLE
确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。
⑤各个隔离级别解决并发问题的能力见下表
⑥各种数据库产品对事务隔离级别的支持程度
注解
用@Transactional注解声明式地管理事务时可以在@Transactional的isolation属性中设置隔离级别
XML
在Spring 2.x事务通知中,可以在<tx:method>元素中指定隔离级别
默认情况
捕获到RuntimeException或Error时回滚,而捕获到编译时异常不回滚。
设置途经
注解
@Transactional 注解
XML
在Spring 2.x事务通知中,可以在<tx:method>元素中指定回滚规则。如果有不止一种异常则用逗号分隔。
简介
由于事务可以在行和表上获得锁,因此长事务会占用资源,并对整体性能产生影响。
如果一个事物只读取数据但不做修改,数据库引擎可以对这个事务进行优化。
超时事务属性:事务在强制回滚之前可以保持多久。这样可以防止长期运行的事务占用资源。
只读事务属性: 表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务。
设置
注解
@Transaction注解
XML
在Spring 2.x事务通知中,超时和只读属性可以在<tx:method>元素中进行指定
举个比较完整的xml配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <context:component-scan base-package="com.atguigu"></context:component-scan> <!--1、配置连接池 --> <bean id="comboPooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="root"></property> <property name="password" value="123456"></property> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/tx"></property> </bean> <!--2、数据库的增删改查 JdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!--3、配置事务切面;控制住连接池 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="comboPooledDataSource"></property> </bean> <!--4、开启基于注解的事务功能;依赖tx名称空间 transaction-manager:指定事务管理器是哪个 --> <!-- <tx:annotation-driven/> --> <!--基于xml的事务配置;需要aop和tx名称空间 --> <!-- transactionManager事务切面 --> <aop:config> <!--指定事务管理器要切入哪些方法进行事务控制 --> <aop:pointcut expression="execution(* com.soyoungboy.service.*.*(..))" id="txPoint"/> <!-- aop:advisor:建议; pointcut-ref:使用指定的切入点表达式切入事务 --> <aop:advisor advice-ref="myTxAdvice" pointcut-ref="txPoint"/> </aop:config> <!-- 使用tx名称空间和配置(事务建议、事务属性、事务增强);事务方法怎么执行 id="myTxAdvice":随便起,别人要引用<aop:advisor advice-ref="myTxAdvice" transaction-manager="transactionManager":指定配置哪个事务管理器 --> <tx:advice id="myTxAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 指定事务方法:代表所有方法是事务方法 --> <tx:method name="*"/> <tx:method name="checkout" rollback-for="java.lang.Exception"/> <tx:method name="updatePrice" propagation="REQUIRES_NEW"/> <!--以get开头的,通过只读来进行优化--> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 基于xml配置的事务控制更多一点 --> </beans>
标签:ice user 存储 sleep 资源 use rom actor ext
原文地址:http://www.cnblogs.com/androidsuperman/p/7361988.html