How I do rollback with spring roo? - persistence

I'm trying to find a method that allows me to do a rollback when one of the elements of a list fails for a reason within the business rules established (ie: when throw my customize exception)
Example, (the idea is not recording anything if one element in list fails)
public class ControlSaveElement {
public void saveRecords(List<MyRecord> listRecords) {
Boolean status = true;
foreach(MyRecord element: listRecords) {
// Here is business rules
if(element.getStatus() == false) {
// something
status = false;
}
element.persist();
}
if(status == false) {
// I need to do roll back from all elements persisted before
}
}
...
}
Any idea? I'm working with Roo 1.2.2..

What you're describing is a service method (saveRecords) that needs to be transactional. Either annotated with the #Transactional annotation and then you raise an exception, or you will have to look into using the TransactionTemplate to get finer control in order to do a manual rollback.
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/transaction.html
http://springinpractice.com/2008/03/18/annotation-based-transactions-in-spring/
is there a way to force a transactional rollback without encountering an exception?

How about creating a new static method in the MyRecord entity:
#Transactional
public static void saveMyRecordsList(List<MyRecord> listRecords) {
boolean persistAll = true;
foreach(MyRecord element: listRecords) {
if(element.getStatus() == false) {
persistAll = false;
}
}
if (persistAll) {
foreach(MyRecord element: listRecords) {
entityManager().persist(element);
}
}
}
This may be more efficient than persisting elements and having to roll them back?

Related

AspNet Boilerplate Parallel DB Access through Entity Framework from an AppService

We are using ASP.NET Zero and are running into issues with parallel processing from an AppService. We know requests must be transactional, but unfortunately we need to break out to slow running APIs for numerous calls, so we have to do parallel processing.
As expected, we are running into a DbContext contingency issue on the second database call we make:
System.InvalidOperationException: A second operation started on this context
before a previous operation completed. This is usually caused by different
threads using the same instance of DbContext, however instance members are
not guaranteed to be thread safe. This could also be caused by a nested query
being evaluated on the client, if this is the case rewrite the query avoiding
nested invocations.
We read that a new UOW is required, so we tried using both the method attribute and the explicit UowManager, but neither of the two worked.
We also tried creating instances of the referenced AppServices using the IocResolver, but we are still not able to get a unique DbContext per thread (please see below).
public List<InvoiceDto> CreateInvoices(List<InvoiceTemplateLineItemDto> templateLineItems)
{
List<InvoiceDto> invoices = new InvoiceDto[templateLineItems.Count].ToList();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(templateLineItems, async (templateLineItem) =>
{
try
{
XAppService xAppService = _iocResolver.Resolve<XAppService>();
InvoiceDto invoice = await xAppService
.CreateInvoiceInvoiceItem();
invoices.Insert(templateLineItems.IndexOf(templateLineItem), invoice);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
if (exceptions.Count > 0) throw new AggregateException(exceptions);
return invoices;
}
How can we ensure that a new DbContext is availble per thread?
I was able to replicate and resolve the problem with a generic version of ABP. I'm still experiencing the problem in my original solution, which is far more complex. I'll have to do some more digging to determine why it is failing there.
For others that come across this problem, which is exactly the same issue as reference here, you can simply disable the UnitOfWork through an attribute as illustrated in the code below.
public class InvoiceAppService : ApplicationService
{
private readonly InvoiceItemAppService _invoiceItemAppService;
public InvoiceAppService(InvoiceItemAppService invoiceItemAppService)
{
_invoiceItemAppService = invoiceItemAppService;
}
// Just add this attribute
[UnitOfWork(IsDisabled = true)]
public InvoiceDto GetInvoice(List<int> invoiceItemIds)
{
_invoiceItemAppService.Initialize();
ConcurrentQueue<InvoiceItemDto> invoiceItems =
new ConcurrentQueue<InvoiceItemDto>();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(invoiceItemIds, (invoiceItemId) =>
{
try
{
InvoiceItemDto invoiceItemDto =
_invoiceItemAppService.CreateAsync(invoiceItemId).Result;
invoiceItems.Enqueue(invoiceItemDto);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
if (exceptions.Count > 0) {
AggregateException ex = new AggregateException(exceptions);
Logger.Error("Unable to get invoice", ex);
throw ex;
}
return new InvoiceDto {
Date = DateTime.Now,
InvoiceItems = invoiceItems.ToArray()
};
}
}
public class InvoiceItemAppService : ApplicationService
{
private readonly IRepository<InvoiceItem> _invoiceItemRepository;
private readonly IRepository<Token> _tokenRepository;
private readonly IRepository<Credential> _credentialRepository;
private Token _token;
private Credential _credential;
public InvoiceItemAppService(IRepository<InvoiceItem> invoiceItemRepository,
IRepository<Token> tokenRepository,
IRepository<Credential> credentialRepository)
{
_invoiceItemRepository = invoiceItemRepository;
_tokenRepository = tokenRepository;
_credentialRepository = credentialRepository;
}
public void Initialize()
{
_token = _tokenRepository.FirstOrDefault(x => x.Id == 1);
_credential = _credentialRepository.FirstOrDefault(x => x.Id == 1);
}
// Create an invoice item using info from an external API and some db records
public async Task<InvoiceItemDto> CreateAsync(int id)
{
// Get db record
InvoiceItem invoiceItem = await _invoiceItemRepository.GetAsync(id);
// Get price
decimal price = await GetPriceAsync(invoiceItem.Description);
return new InvoiceItemDto {
Id = id,
Description = invoiceItem.Description,
Amount = price
};
}
private async Task<decimal> GetPriceAsync(string description)
{
// Simulate a slow API call to get price using description
// We use the token and credentials here in the real deal
await Task.Delay(5000);
return 100.00M;
}
}

IEventBroker subscription handles the same event more than once and handles incorrectly

I am bootstrapping the IEventBroker in a compat-layer Eclipse RCP app.
I have two views: Triggerer and Receiver.
Triggerer (excerpts):
private IEventBroker eventBroker = PlatformUI.getWorkbench().getService(IEventBroker.class);
btn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
IStructuredSelection selection = viewer.getStructuredSelection();
List selectionList = selection.toList();
for (Object s : selectionList) {
if (s instanceof MyObject) {
matches.add(s);
}
}
eventBroker.send(MyEventConstants.TOPIC_OBJECT_CHANGED, matches);
}
}
Receiver (excerpts):
#Override
public void handleEvent(Event event) {
Object data = event.getProperty(EVENT_DATA);
switch (event.getTopic()) {
case MyEventConstants.TOPIC_OBJECT_CHANGED:
try {
if (data instanceof ArrayList) {
List<MyObject> matches = null;
try {
matches = (List<MyObject>) data;
}
catch (ClassCastException e) {
}
Subthing sub = buildSubthing(matches);
getContentViewer().getContents()
.setAll(Collections.singletonList(sub));
}
}
break;
}
}
buildSubthing does stuff with the respective received data, and sets it to the contents of a GEF4 editor.
In some cases this works just fine, in some it doesn't.
handleEvent() is triggered more than once, although the event hashCode is always the same, and I don't understand why. The topic is the same and the data is also the same. However, buildSubthing just stalls for no apprent reason with some data while it doesn't for other. The data is structurally the same in both cases.
How can I control how often handleEvent is called, as I think the number of times it's called is the reason while the Subthing is sometimes not correctly constructed?

Why Shiro's SubjectCallable need invoke restore method?

SubjectCallable's call method:
public V call() throws Exception {
try {
threadState.bind();
return doCall(this.callable);
} finally {
threadState.restore();
}
}
1.bind method is necsssary, but restore is why?
public void bind() {
SecurityManager securityManager = this.securityManager;
if ( securityManager == null ) {
//try just in case the constructor didn't find one at the time:
securityManager = ThreadContext.getSecurityManager();
}
this.originalResources = ThreadContext.getResources();
ThreadContext.remove();
ThreadContext.bind(this.subject);
if (securityManager != null) {
ThreadContext.bind(securityManager);
}
}
public void restore() {
ThreadContext.remove();
if (!CollectionUtils.isEmpty(this.originalResources)) {
ThreadContext.setResources(this.originalResources);
}
}
2.originalResources is use to do ? each time enter the AbstractShiroFilter will create a new subject and invoke it's execute method, the originalResources seems useless.
General thread health. You need to clean up resource in case the thread is re-used (very common). And it would help with garbage collection too.
Do you ever go hiking? Leave no trace ;)

Correct way to call async methods from within a data-bound property setter?

Now I know properties do not support async/await for good reasons. But sometimes you need to kick off some additional background processing from a property setter - a good example is data binding in a MVVM scenario.
In my case, I have a property that is bound to the SelectedItem of a ListView. Of course I immediately set the new value to the backing field and the main work of the property is done. But the change of the selected item in the UI needs also to trigger a REST service call to get some new data based on the now selected item.
So I need to call an async method. I can't await it, obviously, but I also do not want to fire and forget the call as I could miss exceptions during the async processing.
Now my take is the following:
private Feed selectedFeed;
public Feed SelectedFeed
{
get
{
return this.selectedFeed;
}
set
{
if (this.selectedFeed != value)
{
this.selectedFeed = value;
RaisePropertyChanged();
Task task = GetFeedArticles(value.Id);
task.ContinueWith(t =>
{
if (t.Status != TaskStatus.RanToCompletion)
{
MessengerInstance.Send<string>("Error description", "DisplayErrorNotification");
}
});
}
}
}
Ok so besides the fact I could move out the handling from the setter to a synchronous method, is this the correct way to handle such a scenario? Is there a better, less cluttered solution I do not see?
Would be very interested to see some other takes on this problem. I'm a bit curious that I was not able to find any other discussions on this concrete topic as it seems very common to me in MVVM apps that make heavy use of databinding.
I have a NotifyTaskCompletion type in my AsyncEx library that is essentially an INotifyPropertyChanged wrapper for Task/Task<T>. AFAIK there is very little information currently available on async combined with MVVM, so let me know if you find any other approaches.
Anyway, the NotifyTaskCompletion approach works best if your tasks return their results. I.e., from your current code sample it looks like GetFeedArticles is setting data-bound properties as a side effect instead of returning the articles. If you make this return Task<T> instead, you can end up with code like this:
private Feed selectedFeed;
public Feed SelectedFeed
{
get
{
return this.selectedFeed;
}
set
{
if (this.selectedFeed == value)
return;
this.selectedFeed = value;
RaisePropertyChanged();
Articles = NotifyTaskCompletion.Create(GetFeedArticlesAsync(value.Id));
}
}
private INotifyTaskCompletion<List<Article>> articles;
public INotifyTaskCompletion<List<Article>> Articles
{
get { return this.articles; }
set
{
if (this.articles == value)
return;
this.articles = value;
RaisePropertyChanged();
}
}
private async Task<List<Article>> GetFeedArticlesAsync(int id)
{
...
}
Then your databinding can use Articles.Result to get to the resulting collection (which is null until GetFeedArticlesAsync completes). You can use NotifyTaskCompletion "out of the box" to data-bind to errors as well (e.g., Articles.ErrorMessage) and it has a few boolean convenience properties (IsSuccessfullyCompleted, IsFaulted) to handle visibility toggles.
Note that this will correctly handle operations completing out of order. Since Articles actually represents the asynchronous operation itself (instead of the results directly), it is updated immediately when a new operation is started. So you'll never see out-of-date results.
You don't have to use data binding for your error handling. You can make whatever semantics you want by modifying the GetFeedArticlesAsync; for example, to handle exceptions by passing them to your MessengerInstance:
private async Task<List<Article>> GetFeedArticlesAsync(int id)
{
try
{
...
}
catch (Exception ex)
{
MessengerInstance.Send<string>("Error description", "DisplayErrorNotification");
return null;
}
}
Similarly, there's no notion of automatic cancellation built-in, but again it's easy to add to GetFeedArticlesAsync:
private CancellationTokenSource getFeedArticlesCts;
private async Task<List<Article>> GetFeedArticlesAsync(int id)
{
if (getFeedArticlesCts != null)
getFeedArticlesCts.Cancel();
using (getFeedArticlesCts = new CancellationTokenSource())
{
...
}
}
This is an area of current development, so please do make improvements or API suggestions!
public class AsyncRunner
{
public static void Run(Task task, Action<Task> onError = null)
{
if (onError == null)
{
task.ContinueWith((task1, o) => { }, TaskContinuationOptions.OnlyOnFaulted);
}
else
{
task.ContinueWith(onError, TaskContinuationOptions.OnlyOnFaulted);
}
}
}
Usage within the property
private NavigationMenuItem _selectedMenuItem;
public NavigationMenuItem SelectedMenuItem
{
get { return _selectedMenuItem; }
set
{
_selectedMenuItem = val;
AsyncRunner.Run(NavigateToMenuAsync(_selectedMenuItem));
}
}
private async Task NavigateToMenuAsync(NavigationMenuItem newNavigationMenu)
{
//call async tasks...
}

Entity Framework + ODATA: side-stepping the pagination

The project I'm working on has the Entity Framework on top of an OData layer. The Odata layer has it's server side pagination turned to a value of 75. My reading on the subject leads me to believe that this pagination value is used across the board, rather than a per table basis. The table that I'm currently looking to extract all the data from is, of course, more than 75 rows. Using the entity framework, my code is simply thus:
public IQueryable<ProductColor> GetProductColors()
{
return db.ProductColors;
}
where db is the entity context. This is returning the first 75 records. I read something where I could append a parameter inlinecount set to allpages giving me the following code:
public IQueryable<ProductColor> GetProductColors()
{
return db.ProductColors.AddQueryOption("inlinecount","allpages");
}
However, this too returns 75 rows!
Can anyone shed light on how to truly get all the records regardless of the OData server-side pagination stuff?
important: I cannot remove the pagination or turn it off! It's extremely valuable in other scenarios where performance is a concern.
Update:
Through some more searching I've found an MSDN that describes how to do this task.
I'd love to be able to turn it into a full Generic method but, this was as close as I could get to a generic without using reflection:
public IQueryable<T> TakeAll<T>(QueryOperationResponse<T> qor)
{
var collection = new List<T>();
DataServiceQueryContinuation<T> next = null;
QueryOperationResponse<T> response = qor;
do
{
if (next != null)
{
response = db.Execute<T>(next) as QueryOperationResponse<T>;
}
foreach (var elem in response)
{
collection.Add(elem);
}
} while ((next = response.GetContinuation()) != null);
return collection.AsQueryable();
}
calling it like:
public IQueryable<ProductColor> GetProductColors()
{
QueryOperationResponse<ProductColor> response = db.ProductColors.Execute() as QueryOperationResponse<ProductColor>;
var productColors = this.TakeAll<ProductColor>(response);
return productColors.AsQueryable();
}
If unable turn off paging you'll receive 75 row by call, always. You can get all rows in following ways:
Add another IQueryable<ProductColor> AllProductColors and modify
public static void InitializeService(DataServiceConfiguration config)
{
config.UseVerboseErrors = true;
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetEntitySetPageSize("ProductColors", 75); - Note only paged queries are present
config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
You should call ProductColors as many as needed, for example
var cat = new NetflixCatalog(new Uri("http://odata.netflix.com/v1/Catalog/"));
var x = from t in cat.Titles
where t.ReleaseYear == 2009
select t;
var response = (QueryOperationResponse<Title>)((DataServiceQuery<Title>)x).Execute();
while (true)
{
foreach (Title title in response)
{
Console.WriteLine(title.Name);
}
var continuation = response.GetContinuation();
if (continuation == null)
{
break;
}
response = cat.Execute(continuation);
}
I use Rx with following code
public sealed class DataSequence<TEntry> : IObservable<TEntry>
{
private readonly DataServiceContext context;
private readonly Logger logger = LogManager.GetCurrentClassLogger();
private readonly IQueryable<TEntry> query;
public DataSequence(IQueryable<TEntry> query, DataServiceContext context)
{
this.query = query;
this.context = context;
}
public IDisposable Subscribe(IObserver<TEntry> observer)
{
QueryOperationResponse<TEntry> response;
try
{
response = (QueryOperationResponse<TEntry>)((DataServiceQuery<TEntry>)query).Execute();
if (response == null)
{
return Disposable.Empty;
}
}
catch (Exception ex)
{
logger.Error(ex);
return Disposable.Empty;
}
var initialState = new State
{
CanContinue = true,
Response = response
};
IObservable<TEntry> sequence = Observable.Generate(
initialState,
state => state.CanContinue,
MoveToNextState,
GetCurrentValue,
Scheduler.ThreadPool).Merge();
return new CompositeDisposable(initialState, sequence.Subscribe(observer));
}
private static IObservable<TEntry> GetCurrentValue(State state)
{
if (state.Response == null)
{
return Observable.Empty<TEntry>();
}
return state.Response.ToObservable();
}
private State MoveToNextState(State state)
{
DataServiceQueryContinuation<TEntry> continuation = state.Response.GetContinuation();
if (continuation == null)
{
state.CanContinue = false;
return state;
}
QueryOperationResponse<TEntry> response;
try
{
response = context.Execute(continuation);
}
catch (Exception)
{
state.CanContinue = false;
return state;
}
state.Response = response;
return state;
}
private sealed class State : IDisposable
{
public bool CanContinue { get; set; }
public QueryOperationResponse<TEntry> Response { get; set; }
public void Dispose()
{
CanContinue = false;
}
}
}
so for get any data thru OData, create a sequence and Rx does the rest
var sequence = new DataSequence<Product>(context.Products, context);
sequence.OnErrorResumeNext(Observable.Empty<Product>())
.ObserveOnDispatcher().SubscribeOn(Scheduler.NewThread).Subscribe(AddProduct, logger.Error);
The page size is set by the service author and can be set per entity set (but a service may choose to apply the same page size to all entity sets). There's no way to avoid it from the client (which is by design since it's a security feature).
The inlinecount option asks the server to include the total count of the results (just the number), it doesn't disable the paging.
From the client the only way to read all the data is to issue the request which will return the first page and it may contain a next link which you request to read the next page and so on until the last response doesn't have the next link.
If you're using the WCF Data Services client library it has support for continuations (the next link) and a simple sample can be found in this blog post (for example): http://blogs.msdn.com/b/phaniraj/archive/2010/04/25/server-driven-paging-with-wcf-data-services.aspx