简体   繁体   English

Breeze.js的非事务性SaveChanges

[英]Non-Transactional SaveChanges with Breeze.js

Imagine you have a UI that consists of a list of items, each with a checkbox beside them. 假设您有一个由项目列表组成的UI,每个项目旁边都有一个复选框。 You can select multiple checkboxes and click a button to perform a bulk operation. 您可以选择多个复选框,然后单击一个按钮以执行批量操作。 The desire is to have as many of the rows be processed as possible. 希望有尽可能多的行被处理。 So if one row fails, the other selected rows should not roll back. 因此,如果一行失败,则其他选定的行不应回滚。

To do this with Breeze, would it make more sense to send multiple different saves, or is there a way to handle this scenario out of the box? 要使用Breeze做到这一点,发送多个不同的保存是否更有意义,还是有一种现成的方式来处理这种情况?

Sorry. 抱歉。 I am new to Breeze, and have been looking through the docs, samples, and API and can't see any clear indication that this is possible. 我是Breeze的新手,并且一直在浏览文档,示例和API,看不到任何明确的迹象表明这是可能的。 It appears that each call to SaveChanges is transactional. 似乎对SaveChanges的每次调用都是事务性的。 Or is a Named Save required to achieve this behavior? 还是需要命名保存来实现此行为?

Thanks in advance! 提前致谢!

There is no simple way to do a non-transactional batch save in Breeze. 在Breeze中,没有简单的方法可以进行非事务性批处理 You're easiest course is to save each change individually. 您最简单的方法是分别保存每个更改。 You can fire them off in parallel and wait for all to complete if that's important to you. 您可以并行解雇它们,如果对您来说很重要,则可以等待它们完成。

However, if you're game for some serious programming, it can be done. 但是,如果您想进行一些严肃的编程,那么可以做到。 Here is the outline of the approach. 这是该方法的概述。

How to write a non-transactional batch save in Breeze 如何在Breeze中保存非事务性批处理

The easy part is turning off the transaction on the server. 最简单的部分是关闭服务器上的事务。

Take a look at the second parameter of ContextProvider.SaveChanges . 看一下ContextProvider.SaveChanges的第二个参数。 It's a Breeze TransactionSettings object. 这是Breeze TransactionSettings对象。 If you "new" that up you'll get this 如果你“新”了,你会得到这个

public TransactionSettings()
{
  this.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
  this.Timeout = TransactionManager.DefaultTimeout;
  this.TransactionType = TransactionType.None;
}

You can change create one with any value you like but I'm calling attention to TransactionType.None . 您可以使用任何喜欢的值来更改创建一个,但是我要提请注意TransactionType.None

Pass that in your call to SaveChanges 在通话中将其传递给SaveChanges

    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        return _contextProvider.SaveChanges(saveBundle, myTransactionSettings);
    }

I believe that will prevent the EFContextProvider from saving transactionally. 我相信这将防止EFContextProvider进行事务保存。

Now you have to fix things on the client side. 现在,您必须在客户端修复问题。 I haven't turned off transactions so I'm not familiar with how errors are caught and transmitted to the client. 我没有关闭事务,所以我不熟悉如何捕获错误并将错误传输给客户端。

The real challenge is on the client. 真正的挑战在于客户。 You have to do something when the save fails partially. 保存部分失败时,您必须执行某些操作。 You have to help the Breeze EntityManager figure out which entities succeeded and which failed and process them appropriately ... or your entity cache will become unstable. 您必须帮助Breeze EntityManager找出成功的实体和失败的实体,并适当地处理它们……否则您的实体缓存将变得不稳定。

You will have to write a custom Data Service Adapter with some very tricky save processing logic. 您将必须编写具有一些非常棘手的保存处理逻辑的自定义数据服务适配器 That is not easy! 那不容易!

I've done it in my Breeze Labs Abstract Rest Adapter which is not documented and quite complex. 我已经在我的Breeze Labs Abstract Rest Adapter中完成了此操作,该文件尚未记录且非常复杂。 You're welcome to read it and apply its reasoning to your own implementation of the "web api" Data Service Adapter. 欢迎您阅读它并将其推理应用于您自己的“ Web API”数据服务适配器的实现。 If you have budget, you might engage IdeaBlade professional services (makers of Breeze) 如果您有预算,可以参加IdeaBlade专业服务(Breeze的制造商)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM