针对一个账号进入存钱、取钱操作的并发控制,hibernate version乐观锁

这几天在练习针对一个账号进行存钱、取钱操作的并发控制。

 

entiy:Account

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;

import java.io.Serializable;

@Entity(name = "Account")
public class Account implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "AccountNumber")
    private String accountNumber;
    
   /* @Version
    @Column(name = "Version")
    private long version;*/
    
    @Column(name = "Status")
    private String status;
    
    @Column(name = "Score")
    private Double score;
    
    @Column(name = "Cas")
    private Long cas;

    
    public String getAccountNumber() {
        return accountNumber;
    }
    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }
    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    public Long getCas() {
        return cas;
    }

    public void setCas(Long cas) {
        this.cas = cas;
    }    
}
    

 

 

dao:AccountDao

import org.springframework.stereotype.Repository;
import javax.inject.Inject;
import javax.persistence.FlushModeType;

@Repository
public class AccountDao {

    private ProductionJPAAccess productionJpaAccess;

    public Account get(String accountNumber) {
        return productionJpaAccess.get(Account.class, accountNumber);
    }

    public void save(Account account) {
        productionJpaAccess.save(account);
    }

    public void update(Account account) {
        //System.out.println(productionJpaAccess.getEntityManager().getFlushMode());
        //productionJpaAccess.getEntityManager().setFlushMode(FlushModeType.COMMIT);
        productionJpaAccess.update(account);
        productionJpaAccess.getEntityManager().flush();
    }
    
    @Inject
    public void setProductionJpaAccess(ProductionJPAAccess productionJpaAccess) {
        this.productionJpaAccess = productionJpaAccess;
    }
}

 

 

service: TradeService

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Inject;

@Service
public class TradeService {
    private final Logger logger = LoggerFactory.getLogger(TradeService.class);

    private AccountDao accountDao;

    private DataConverter dataConverter;

    @Inject
    private GenIdentityDao genIdentityDao;

    public Account get(String accountNumber) {
        return accountDao.get(accountNumber);
    }    
    
    @Transactional(value = "transactionManager",  propagation=Propagation.REQUIRED)    
    public synchronized void handleSimple(String accountNumber, double amount, boolean deposit) throws ResourceNotFoundException, NotEnoughException {
       // logger.error("{}, enter, {}", Thread.currentThread().getName(), this.hashCode());
        Account account = get(accountNumber);
        if (account == null) {
           throw new ResourceNotFoundException("account(" + accountNumber + ") not found");
        }

        double score = account.getScore();
        if (deposit) {
            account.setScore(convert(account.getScore() + amount));
        } else {
            if (account.getScore() < amount) {
                logger.error("--------------------" + Thread.currentThread().getName() + " " + accountNumber + ":" + score + (deposit ? "+" : "-") + amount + " failed");
               throw new NotEnoughException("account(" + accountNumber + ") not enough");
            }
            account.setScore(convert(account.getScore() - amount));

        }

        // account.setCas(account.getCas() + 1);
        accountDao.update(account);
        logger.error("-----" + Thread.currentThread().getName() + " " + accountNumber + ":" + score + (deposit ? "+" : "-") + amount + "=" + account.getScore());
    }

    
    public double convert(double value) {
        long lg = Math.round(value * 100);
        double d = lg / 100.0;
        return d;
    }

    @Transactional(value = "transactionManager")
    public void saveAccount(Account account) {
        accountDao.save(account);
    }

    @Inject
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Inject
    public void setDataConverter(DataConverter dataConverter) {
        this.dataConverter = dataConverter;
    }

}

 

 

用了多线程模拟多个请求,

task:MultipleTask

 

import java.util.Random;

public class MultipleTask implements Runnable {

    private TradeService tradeService;

    public MultipleTask(TradeService tradeService) {
        this.tradeService = tradeService;
    }

    @Override
    public void run() {
        String accountNumber = "SYS5";

        Random r = new Random();
        double amount = r.nextDouble() * 10;
        amount = convert(amount);
        boolean deposit = r.nextBoolean();

        try {
            Thread.sleep(r.nextInt(100));
        } catch (InterruptedException e) {
        }

        try {
            tradeService.handleSimple(accountNumber, amount, deposit);
        } catch (ResourceNotFoundException e) {
            e.printStackTrace();
        } catch (NotEnoughException e) {
            e.printStackTrace();
        }
    }

    public double convert(double value) {
        long lg = Math.round(value * 100);
        double d = lg / 100.0;
        return d;
    }

}

 

 

测试类:

 

@Test
    public void testMultiple() throws Exception {
       

        for (int i = 0; i < 30; i++) {
            MultipleTask m = new MultipleTask(tradeService);
            new Thread(m, i + "").start();

        }

        Thread.sleep(1000000000);
    }

 

特别要注意:

1.一定要在accountDao.update()方法的最后加上立即flush的语句,防止因没及时flush,其他线程访问到提交前的数据。

productionJpaAccess.getEntityManager().flush();

 

2.一定要在handleSimple方法里重新从数据库load对象,判断是否存在(已被别的线程删除?)、是否足够(已被别的线程取掉了一些钱?),然后更新。即让重新load,各种判断在synchronized管制之内。

如果这几个判断在synchronized管制之外,有可能A线程在判断通过后,等待B线程执行synchronized代码,然后A进入synchronized代码时,数据已经被改变了,即原来的判断就不正确了。

 

3.在test方法中加上 Thread.sleep(1000000000);是为了防止主线程停止后spring容器被关闭。

 

 

 测试结果:

2014-04-24 13:35:22,399 [2] ERROR TradeService - -----2 SYS5:2.5+1.11=3.61
2014-04-24 13:35:22,413 [29] ERROR TradeService - -----29 SYS5:3.61-1.12=2.49
2014-04-24 13:35:22,414 [15] ERROR TradeService - --------------------15 SYS5:2.49-9.33 failed
2014-04-24 13:35:22,417 [27] ERROR TradeService - -----27 SYS5:2.49+4.06=6.55
2014-04-24 13:35:22,420 [23] ERROR TradeService - -----23 SYS5:6.55+1.61=8.16
2014-04-24 13:35:22,424 [17] ERROR TradeService - -----17 SYS5:8.16+3.82=11.98
2014-04-24 13:35:22,426 [7] ERROR TradeService - -----7 SYS5:11.98+9.48=21.46
2014-04-24 13:35:22,431 [21] ERROR TradeService - -----21 SYS5:21.46+2.91=24.37
2014-04-24 13:35:22,434 [5] ERROR TradeService - -----5 SYS5:24.37-4.36=20.01
2014-04-24 13:35:22,436 [19] ERROR TradeService - -----19 SYS5:20.01+2.95=22.96
2014-04-24 13:35:22,439 [3] ERROR TradeService - -----3 SYS5:22.96-2.72=20.24
2014-04-24 13:35:22,442 [11] ERROR TradeService - -----11 SYS5:20.24-2.25=17.99
2014-04-24 13:35:22,444 [25] ERROR TradeService - -----25 SYS5:17.99+3.97=21.96
2014-04-24 13:35:22,447 [13] ERROR TradeService - -----13 SYS5:21.96+6.31=28.27
2014-04-24 13:35:22,450 [9] ERROR TradeService - -----9 SYS5:28.27+3.7=31.97
2014-04-24 13:35:22,454 [28] ERROR TradeService - -----28 SYS5:31.97-4.84=27.13
2014-04-24 13:35:22,460 [26] ERROR TradeService - -----26 SYS5:27.13+2.29=29.42
2014-04-24 13:35:22,464 [8] ERROR TradeService - -----8 SYS5:29.42-1.73=27.69
2014-04-24 13:35:22,466 [0] ERROR TradeService - -----0 SYS5:27.69-9.4=18.29
2014-04-24 13:35:22,469 [16] ERROR TradeService - -----16 SYS5:18.29+2.03=20.32
2014-04-24 13:35:22,472 [22] ERROR TradeService - -----22 SYS5:20.32+2.58=22.9
2014-04-24 13:35:22,475 [24] ERROR TradeService - -----24 SYS5:22.9-3.39=19.51
2014-04-24 13:35:22,477 [1] ERROR TradeService - -----1 SYS5:19.51+2.27=21.78
2014-04-24 13:35:22,480 [14] ERROR TradeService - -----14 SYS5:21.78-8.68=13.1
2014-04-24 13:35:22,485 [10] ERROR TradeService - -----10 SYS5:13.1-2.81=10.29
2014-04-24 13:35:22,488 [18] ERROR TradeService - -----18 SYS5:10.29-1.59=8.7
2014-04-24 13:35:22,491 [4] ERROR TradeService - -----4 SYS5:8.7-2.44=6.26
2014-04-24 13:35:22,523 [12] ERROR TradeService - --------------------12 SYS5:6.26-6.56 failed
2014-04-24 13:35:22,526 [20] ERROR TradeService - -----20 SYS5:6.26+6.03=12.29
2014-04-24 13:35:22,532 [6] ERROR TradeService - -----6 SYS5:12.29+7.46=19.75

 

 

以上是自己实现的同步控制,适于只部署一台服务器。

如果是分布式环境,多个tomcat,用synchronized就没法控制了。

这时候就需要使用hibernate version,乐观锁。

 

hiberate里使用乐观锁很简单,在entity上加一个long类型的属性version,加上@Version,get,set。。

@Version
@Column(name = "Version")
 private long version;

 

然后就可以正常的save,update了。

在更新时会自动加上 , version = ?, update XX set XXXX where id=?, version = ?

如果记录已经被更新了,version就会加1,就找不到这条记录更新不了了,会抛出OptimisticLockException异常。

 

 

 

 

@Test
    public void testVersion() {
        Account a = new Account();
        a.setAccountNumber("SYS7");
        a.setScore(10d);
        tradeService.saveAccount(a);

       // a = tradeService.get("SYS7");
        System.out.println(a.getVersion());

        for (int i = 0; i < 5; i++) {
            a.setScore(a.getScore() + 1);
            tradeService.update(a);
            
            //a = tradeService.get("SYS7");
            System.out.println(a.getVersion());
        }    
    }

 以上代码会抛出javax.persistence.OptimisticLockException异常,因为update后,数据库的version已经更新了,但a还没更新。所以得重新get出来。

 

@Test
    public void testVersion() {
        Account a = new Account();
        a.setAccountNumber("SYS7");
        a.setScore(10d);
        tradeService.saveAccount(a);

        a = tradeService.get("SYS7");
        System.out.println(a.getVersion());

        for (int i = 0; i < 2; i++) {
            a.setScore(11d);
            tradeService.update(a);
            
            a = tradeService.get("SYS7");
            System.out.println(a.getVersion());
        }    
    }

 以上代码打印结果是

0

1

1

因为2次都是把score set成11d,其实值没变,update就没真正执行,也就不会使version增加。

 

 

@Test
    public void testVersion() {
        Account a = new Account();
        a.setAccountNumber("SYS7");
        a.setScore(10d);
        tradeService.saveAccount(a);

        a = tradeService.get("SYS7");
        System.out.println(a.getVersion());

        for (int i = 0; i < 2; i++) {
            a.setScore(a.getScore() + 1);
            tradeService.update(a);
            
            a = tradeService.get("SYS7");
            System.out.println(a.getVersion());
        }    
    }

以上代码打印

0

1

2

是正常的。

Oracle 11g版本下载及安装超详细教程图解 新手Oracle安装教程 阅读详情

相关推荐

从原始数据到农学模型:DJI M3M/P4M多光谱影像全链路处理实战

本文详细介绍了使用DJI M3M/P4M多光谱无人机进行农学建模的全链路流程。核心在于强调辐射标定的首要性,它将原始DN值转换为具有物理意义的反射率,是确保后续植被指数计算与模型反演准确性的基石。文章通过大疆智图和Pix4Dfields的实战演示,手把手指导完成数据处理、影像镶嵌及光谱信息提取,最终构建从光谱指数到叶面积指数等关键农学参数的反演模型,实现精准农业分析。

weixin_29281941的博客 243

高并发下,用户余额扣减保证一致

1,可以通过队列的方式处理; 2,参见:https://m.wang1314.com/doc/webapp/topic/20483105.html 高并发下,余额扣减一致性实践 藏家004收藏于2018-11-01 转藏1次 缘起:在高并发的分布式环境下,对于数据的查询与修改容易引发一致性问题,本文将分享一种非常简单但有效的优化方法。 一、业务场景 业务场景为,购买商品的过程要对余额进行查询与修改,大致的业务流程如下: (1)从数据库查询用户现有余额 SELECT money FRO...

brazor的博客 2456

《机器人学一(Robotics(1))》_台大林沛群 第 3 周 【机械手臂 顺运动学】Quiz 3

的方向,旋转方向与四指弯曲方向相反,为负, α为 -90。的方向,旋转方向与四指弯曲方向相反,为负, α为 -90。bug 的图 要求解的 i 位置有误 两套 题目?B. 第2个 坐标系 的原点位置 不便于 计算;上面的正确,后两题 有误, 不知道问题在哪里。标准部分, 前面的更常用,这种仅作为 了解。还是计算过程中保留两位有效数字 不符合。2、确定 旋转角 α 正负的右手定则。1、确定坐标系方向的右手定则。可相交,距离为 0。A: 右手拇指指向。小数点后两位,不符合。

weixin_46034116的博客 1242

高并发下余额扣减

添加数据库行锁 当请求A执行是 先加入锁阻塞 请求B直到 请求A完成之后 请求B才继续执行 //开始事务 begin; //消费金额 $spend = 10; //查询用户余额 $user = select id,fee from users where id = 12 for update; //计算金额 $newFee = $user['fee'] - $spend; //...检查余...

qq_19557947的专栏 2088

生物信息学新手必看:MAFFT多序列比对从安装到实战(附参数优化技巧)

本文为生物信息学新手提供了MAFFT多序列比对工具的完整指南。从Linux环境下的安装部署,到核心算法策略(如FFT-NS-i、L-INS-i)的选择逻辑,再到空位罚分等关键参数的深度解析与优化技巧,手把手教你完成从原始序列到高质量比对结果的实战流程,为后续进化树构建等分析奠定坚实基础。

weixin_29230773的博客 484

电源芯片TPS54560典型应用电路及设计详解

TPS54560 是一款配有集成型高侧 MOSFET 的 60V、5A DC-DC转换器,输入电压范围7-60V,输出电压可通过外部反馈电阻设置成略低于输入电压的任意值。**所以,**R5=31.25KΩ、R6:10KΩ(常用值)时,即可设置输出电压为 3.3V。**所以,**R5=140KΩ、R6:10KΩ(常用值)时,即可设置输出电压为12V。设计 TPS54560 的输出电压时,主要通过外部反馈电阻网络来设置输出电压。因此,输出 3.3V ,输入电压24V时推荐的电感值为 8µH 至 10µH。

weixin_42306872的博客 1万+

金额操作中的并发事务问题

背景: 关于金额操作的并发事务如何处理是个经典问题,相信很多人都会遇到类似的需求,这里讨论下如何解决此类需求 ~ 一、需求 一个用户查询请求过来,首先需要数据库查询用户余额是否足够,如果不足则返回余额不足,如果足够则调用第三方接口查询(预计花费2s),如果第三方接口返回true则正常扣费,update用户余额,如果第三方接口返回false或者代码发生异常,则本次查询不扣费。 伪代码如下: pub...

Abysscarry的博客 4376

BDD测试之Behave使用入门

BDD测试(Behavior-Driven Development Testing)是一种基于“行为驱动开发”(BDD)理念。

想要成为酷盖但是失败的小明 580

【锁】银行存取钱情景下的乐观锁与悲观锁实现

【锁】银行存取钱情景下的乐观锁与悲观锁实现。

qq_43530796的博客 376

保姆级教程:在Android车机上从零配置USB Gadget,搞定CarPlay有线连接

本文详细介绍了在Android车机上从零配置USB Gadget以实现CarPlay有线连接的完整实践指南。涵盖内核驱动开发、Android系统配置及用户空间通信架构,帮助开发者深入理解USB子系统和iAP2协议栈,实现稳定可靠的CarPlay有线连接功能。

weixin_30621711的博客 472

Hibernate JPA 悲观锁,乐观锁

1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。 基于jdbc实现的数据库加锁如下: select * from account...

chuixuan3775的博客 281

Claude Code 100个真实案例 - 用AI设计Arduino PCB电路板(硬件小白也能画板)

本案例展示如何使用 Claude Code 配合 KiCad 的 Python 脚本接口,从零设计一块 Arduino 传感器扩展板 PCB。从原理图符号创建、网表生成到 PCB 布局布线,全程自动化完成,最终输出可直接发给工厂打样的 Gerber 文件。

yueyeguzhuo的专栏 438

Hibernate锁机制 悲观锁和乐观锁

1、Pessimistic Locking 悲观锁;     pessimistic [,pesimistik] adj. 悲观的,厌世的;悲观主义的2、Optimistic   Locking 乐观锁;     optimistic   [,ɔptimistik]    adj. 乐观的;乐观主义的 一、hibernate锁机制 1.悲观锁 它指的是对数据被外界修

哥只是个传说,不要迷恋哥 1313

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Hibernate,悲观锁,乐观锁(二)

1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。 基于jdbc实现的数据库加锁如下: select * from account where name="Erica" for update 在

想念的专栏 345

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Hibernate锁机制--悲观锁和乐观锁

 hibernate锁机制,今天写个总结。Hibernate锁机制包括悲观锁和乐观锁。 1.悲观锁它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。基于jdbc实现的数据库加锁如下:select * from accoun

TERRY的技术日志 1028

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Hibernate锁机制_悲观锁和乐观锁

1、Pessimistic Locking 悲观锁; pessimistic [,pesi'mistik] adj. 悲观的,厌世的;悲观主义的 2、Optimistic Locking 乐观锁; optimistic [,?pti'mistik] adj. 乐

hjh333123的专栏 340

Hibernate锁机制:悲观锁与乐观锁

1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。 基于jdbc实现的数据库加锁如下: select * from account where name="Erica" for update 在更新的过程中,数...

cowbane 108

Hibernate 悲观锁,乐观锁

1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。基于jdbc实现的数据库加锁如下: select * from account where name="Erica" for update 在更新的过程中...

weixin_34107739的博客 80

Hibernate的锁机制

<br />hibernate锁机制<br /> 1.悲观锁<br />它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。<br /> 基于jdbc实现的数据库加锁如下:<br />select * from account where name=”Erica” for update<br />在更新的过程中,数据库处于加锁状态,任何其他的针对本条数据的操作都

priestmoon的专栏 451

hibernate悲观锁与乐观锁(一)

1.悲观锁 它指的是对数据被外界修改持保守态度。假定任何时刻存取数据时,都可能有另一个客户也正在存取同一笔数据,为了保持数据被操作的一致性,于是对数据采取了数据库层次的锁定状态,依靠数据库提供的锁机制来实现。 基于jdbc实现的数据库加锁如下: [code="sql"]select * from account where name="Erica" for update[/code]...

VooleBoy的专栏 155
上一篇: (转)为你的Web程序加个启动画面
下一篇: 转:tomcat session——对session的支持
Brage_Lin
博客等级 码龄20年 5粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值