jjzjj

java - Ibatis startBatch() 仅适用于 SqlMapClient 自己的启动和提交事务,不适用于 Spring 管理的事务

coder 2023-10-12 原文

我发现即使我有 Spring 事务包装的代码,并且它会在我期望的时候提交/回滚,为了在使用 Ibatis 和 Spring 时使用 JDBC 批处理,我需要使用显式 SqlMapClient 事务方法.

即这确实像我期望的那样进行批处理:

dao.getSqlMapClient().startTransaction();
dao.getSqlMapClient().startBatch();

int i = 0;
for (MyObject obj : allObjects)
{
    dao.storeChange(obj);

    i++;
    if (i % DB_BATCH_SIZE == 0)
    {
        dao.getSqlMapClient().executeBatch();
        dao.getSqlMapClient().startBatch();
    }
}

dao.getSqlMapClient().executeBatch();
dao.getSqlMapClient().commitTransaction();

但如果我没有打开和关闭事务语句,并且依赖 Spring 来管理事物(这正是我想做的!),批处理就不会发生。

鉴于 Spring 在其他方面似乎确实处理了它在事务管理方面的讨价还价,任何人都可以就此处的任何已知问题提出建议吗?

(数据库是 MySQL;我知道关于它的 JDBC 伪批处理方法和 INSERT 语句重写的问题,这在这里绝对不是问题)

最佳答案

通过阅读各种资源和反复试验找到了这背后的原因,我在这里记录了我们的结果,因为它可能对其他人有帮助。

事实证明,不同的行为是由于我们的 DAO 类扩展了 Spring 的 SqlMapClientTemplate。在那堂课上你有两个“选择”(我说的是选择;一个是正确的,一个不是):

  • 直接使用insert()、update()等;一路使用完整的Spring对象

  • getSqlMapClient().insert()、update()等;这个实际上使用由 getSqlMapClient() 返回的 com.ibatis... 对象而不是 Spring 对象工作

两者通常都有效,但根据我的阅读,第一个选项更好,例如如果您正在使用 Spring,您希望完全基于 Spring,而不是“跳出”到 Ibatis 对象。

现在,SqlMapClientTemplate 不直接提供对 startBatch()/executeBatch() 的访问,只提供方便的 insert()、update() 东西,所以像这样的代码是执行这类事情所必需的。下面的代码完全适用于我们的 Spring 管理事务,而不是可见的显式代码 startTransaction()。

(为了清楚起见,由于我的“匿名”工作代码,这可能包含错误的免责声明)

public class MyFunkyDao extends SqlMapClientDaoSupport
{
    private static final int DB_BATCH_SIZE = 1000;

    public void storeMyData(final List<MyData> listData)
    {
        getSqlMapClientTemplate().execute( new SqlMapClientCallback()
        {
            @Override
            public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException
            {
                int count = 0, total = 0;

                Map<String, Object> params = new HashMap<String, Object>();

                executor.startBatch();

                for (MyData data: listData)
                {
                    params.put("param name 1", data.getValue());

                    executor.insert("insertData", params);

                    count++;
                    if (count % DB_BATCH_SIZE == 0) 
                    {
                        total += executor.executeBatch();
                        executor.startBatch();
                    }

                    params.clear();
                }

                total += executor.executeBatch();

                return new Integer(total);
            }
        });
    }
}

链接:http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/orm/ibatis/SqlMapClientTemplate.html

关于java - Ibatis startBatch() 仅适用于 SqlMapClient 自己的启动和提交事务,不适用于 Spring 管理的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2921840/

有关java - Ibatis startBatch() 仅适用于 SqlMapClient 自己的启动和提交事务,不适用于 Spring 管理的事务的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  3. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  4. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  5. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  6. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  7. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  8. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  9. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  10. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

随机推荐