user=LF password=LF jdbcUrl=jdbc:oracle:thin:@localhost:1521:orcl driverClass=oracle.jdbc.driver.OracleDriver initialPoolSize=15 maxPoolSize=30 minPoolSize=5
<?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" 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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置自动扫描的包 --> <context:component-scan base-package="com.zr.trasaction"></context:component-scan> <!-- 引用外部文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置dataSource --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="user" value="${user}"></property> <property name="password" value="${password}"></property> <property name="jdbcUrl" value="${jdbcUrl}"></property> <property name="driverClass" value="${driverClass}"></property> <property name="initialPoolSize" value="${initialPoolSize}"></property> <property name="maxPoolSize" value="${maxPoolSize}"></property> <property name="minPoolSize" value="${minPoolSize}"></property> </bean> <!-- 配置jdbcTemplate --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 配置事务声明方式 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
package com.zr.trasaction.entity; public class Amount { private String user;//用户名 private double money;//金额 public String getUser() { return user; } public void setUser(String user) { this.user = user; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public Amount() { super(); } public Amount(String user, double money) { super(); this.user = user; this.money = money; } @Override public String toString() { return "Amount [user=" + user + ", money=" + money + "]"; } }
package com.zr.trasaction.entity; public class BalanceException extends RuntimeException { private static final long serialVersionUID = 1L; public BalanceException() { super(); } public BalanceException(String message) { super(message); } public BalanceException(String message, Throwable cause) { super(message, cause); } public BalanceException(Throwable cause) { super(cause); } protected BalanceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
package com.zr.trasaction.dao; public interface AmountDao { /** * 转出钱 * @return */ public boolean decreaseMoney(String username,double money) ; /** * 转入钱 * @return */ public boolean increaseMoney(String username,double money); }
package com.zr.trasaction.daoImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.zr.trasaction.dao.AmountDao; @Repository public class AmountDaoImpl implements AmountDao { @Autowired(required=true) private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public boolean decreaseMoney(String username, double money) { String sql = "UPDATE TEST SET MONEY=MONEY-? WHERE USERNAME=?"; int i = -1; i = jdbcTemplate.update(sql,money, username); if(i>0){ return true; } return false; } @Override public boolean increaseMoney(String username, double money) { String sql = "UPDATE TEST SET MONEY=MONEY+? WHERE USERNAME=?"; int i = -1; i = jdbcTemplate.update(sql,money, username); if(i>0){ return true; } return false; } }
package com.zr.trasaction.Service; import com.zr.trasaction.entity.Amount; public interface AmountService { /** * 转账业务 * @param desAmount 扣钱的账户 * @param incAmount 增加的账户 * @param money 转账的金额 * @return */ public boolean transferMoneyService(Amount desAmount,Amount incAmount,double money); }
package com.zr.trasaction.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; 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.zr.trasaction.Service.AmountService; import com.zr.trasaction.daoImpl.AmountDaoImpl; import com.zr.trasaction.entity.Amount; import com.zr.trasaction.entity.BalanceException; @Service("amountServiceImpl") public class AmountServiceImpl implements AmountService { @Autowired(required=true) private AmountDaoImpl amountDaoImpl; @Autowired(required=true) private JdbcTemplate jdbcTemplate; public void setAmountDaoImpl(AmountDaoImpl amountDaoImpl) { this.amountDaoImpl = amountDaoImpl; } public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * REQUIRED(默认值):在有transaction状态下执行;如当前没有transaction,则创建新的transaction * 只读事务属性readOnly=true: 表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务 * 超时事务属性timeout=3: 事务在强制回滚之前可以保持多久. 这样可以防止长期运行的事务占用资源.单位为秒,一般不设置,使用默认的 * noRollbackForClassName={"BalanceException"} 发生BalanceException异常不回滚 */ @Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.READ_COMMITTED,readOnly=true,timeout=3/*,noRollbackForClassName={"BalanceException"}*/) @Override public boolean transferMoneyService(Amount desAmount, Amount incAmount, double money) { String sql = "SELECT MONEY FROM TEST WHERE USERNAME=?"; double balance = jdbcTemplate.queryForObject(sql, Double.class, desAmount.getUser()); boolean success1 = amountDaoImpl.decreaseMoney(desAmount.getUser(), money); boolean success2 = amountDaoImpl.increaseMoney(incAmount.getUser(), money); if(balance < money){ throw new BalanceException("余额不足"); } return success1 && success2; } }
package com.zr.trasaction.test; import javax.sql.DataSource; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.jdbc.core.JdbcTemplate; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.zr.trasaction.Service.AmountService; import com.zr.trasaction.ServiceImpl.AmountServiceImpl; import com.zr.trasaction.daoImpl.AmountDaoImpl; import com.zr.trasaction.entity.Amount; public class TestA { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Amount desAmount = new Amount("lf", 0); Amount incAmount = new Amount("tl", 0); AmountService impl = (AmountService) ac.getBean("amountServiceImpl"); boolean isSuccess = impl.transferMoneyService(desAmount, incAmount, 10); } }
时间: 2024-10-12 08:37:35