数据库余额表:本来想用版本号来实现的,后面弃用version字段。
DROP TABLE IF EXISTS `t_test`;
CREATE TABLE `t_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` decimal(11,2) DEFAULT NULL,
`version` int(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `t_test` VALUES ('1', '50.00', '1');
mapper.xml文件:仔细看两个sql的写法,这里是重点,请不要在java代码中进行余额的加减操做。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.taotao.mapper.TTestMapper" >
<resultMap id="BaseResultMap" type="com.taotao.pojo.TTest" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="account" property="account" jdbcType="DECIMAL" />
<result column="version" property="version" jdbcType="INTEGER" />
</resultMap>
<update id="updateAccountAdd" parameterType="com.taotao.pojo.TTest" >
update t_test
set account = account + #{newAccount,jdbcType=DECIMAL}
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateAccountSub" parameterType="com.taotao.pojo.TTest" >
update t_test
set account = account - #{newAccount,jdbcType=DECIMAL}
where id = #{id,jdbcType=INTEGER} and account >= #{newAccount,jdbcType=DECIMAL}
</update>
</mapper>
service:请在每一个方法上加入事物和synchronized。
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TTestMapper testMapper;
/**
* 存钱
*
* @param money
*/
@Override
@Transactional
public synchronized BigDecimal addAcount(String name, int money) throws TransactionalException {
TTest tTest = testMapper.selectByPrimaryKey(1);
tTest.setNewAccount(new BigDecimal(money));
int i = testMapper.updateAccountAdd(tTest);
if (i == 0){
System.out.println("添加余额失败!余额=" + tTest.getAccount());
return new BigDecimal(money);
}
System.out.println(name + "...存入:" + money + "..." + Thread.currentThread().getName());
return selectAcount(name);
}
/**
* 取钱
*
* @param money
*/
@Override
@Transactional
public synchronized BigDecimal subAcount(String name, int money) throws TransactionalException{
TTest tTest = testMapper.selectByPrimaryKey(1);
tTest.setNewAccount(new BigDecimal(money));
int i = testMapper.updateAccountSub(tTest);
if (i == 0){
System.out.println("帐户余额不足!余额=" + tTest.getAccount());
return new BigDecimal(money);
}
System.out.println(name + "...取出:" + money + "..." + Thread.currentThread().getName());
return selectAcount(name);
}
/**
* 查询余额
*/
@Override
@Transactional
public synchronized BigDecimal selectAcount(String name) throws TransactionalException{
TTest tTest = testMapper.selectByPrimaryKey(1);
System.out.println(name + "...余额:" + tTest.getAccount());
return tTest.getAccount();
}
}
@Controller
public class TestMysqlController {
@Autowired
private TestService testService;
@RequestMapping(value="/cardAddAcountMysql")
@ResponseBody
public TaotaoResult<Integer> cardAddAcount() throws TransactionalException{
TaotaoResult<Integer> result = new TaotaoResult<Integer>();
result.setData("+100, 余额: " + testService.addAcount("card", 100));
return result;
}
@RequestMapping(value="/passbookAddAcountMysql")
@ResponseBody
public TaotaoResult<Integer> passbookAddAcount() throws TransactionalException{
TaotaoResult<Integer> result = new TaotaoResult<Integer>();
result.setData("+100, 余额: " + testService.addAcount("存折", 100));
return result;
}
@RequestMapping(value="/cardSubAcountMysql")
@ResponseBody
public TaotaoResult<Integer> cardSubAcount(){
TaotaoResult<Integer> result = new TaotaoResult<Integer>();
result.setData("-150, 余额: " + testService.subAcount("card", 150));
return result;
}
@RequestMapping(value="/passbookSubAcountMysql")
@ResponseBody
public TaotaoResult<Integer> passbookSubAcount() throws TransactionalException{
TaotaoResult<Integer> result = new TaotaoResult<Integer>();
result.setData("-200, 余额: " + testService.subAcount("存折", 200));
return result;
}
@RequestMapping(value="/selectAcountMysql")
@ResponseBody
public TaotaoResult<Integer> selectAcount() throws TransactionalException {
TaotaoResult<Integer> result = new TaotaoResult<Integer>();
result.setData(testService.selectAcount(""));
return result;
}
}
评论 (0)